diff options
51 files changed, 524 insertions, 150 deletions
diff --git a/ci/Containerfile b/contrib/ci/Containerfile index 8b0792166..8b0792166 100644 --- a/ci/Containerfile +++ b/contrib/ci/Containerfile diff --git a/ci/jobs/0-codespell/config.ini b/contrib/ci/jobs/0-codespell/config.ini index 1c52b6a1a..bd7d73860 100644 --- a/ci/jobs/0-codespell/config.ini +++ b/contrib/ci/jobs/0-codespell/config.ini @@ -3,3 +3,4 @@ HALT_ON_FAILURE = False WARN_ON_FAILURE = True CONTAINER_BUILD = False CONTAINER_NAME = nixery.dev/shell/codespell +CONTAINER_ARCH = amd64 diff --git a/ci/jobs/0-codespell/dictionary.txt b/contrib/ci/jobs/0-codespell/dictionary.txt index b4d643349..b4d643349 100644 --- a/ci/jobs/0-codespell/dictionary.txt +++ b/contrib/ci/jobs/0-codespell/dictionary.txt diff --git a/ci/jobs/0-codespell/job.sh b/contrib/ci/jobs/0-codespell/job.sh index 58bd07b5a..58bd07b5a 100755 --- a/ci/jobs/0-codespell/job.sh +++ b/contrib/ci/jobs/0-codespell/job.sh diff --git a/ci/jobs/1-build/build.sh b/contrib/ci/jobs/1-build/build.sh index b11374291..b11374291 100755 --- a/ci/jobs/1-build/build.sh +++ b/contrib/ci/jobs/1-build/build.sh diff --git a/ci/jobs/1-build/job.sh b/contrib/ci/jobs/1-build/job.sh index 8d79902c5..8d79902c5 100755 --- a/ci/jobs/1-build/job.sh +++ b/contrib/ci/jobs/1-build/job.sh diff --git a/ci/jobs/2-test/job.sh b/contrib/ci/jobs/2-test/job.sh index bfb24e335..bfb24e335 100755 --- a/ci/jobs/2-test/job.sh +++ b/contrib/ci/jobs/2-test/job.sh diff --git a/ci/jobs/2-test/test.sh b/contrib/ci/jobs/2-test/test.sh index 39fca5c16..39fca5c16 100755 --- a/ci/jobs/2-test/test.sh +++ b/contrib/ci/jobs/2-test/test.sh diff --git a/ci/jobs/3-docs/docs.sh b/contrib/ci/jobs/3-docs/docs.sh index fe2b96873..fe2b96873 100755 --- a/ci/jobs/3-docs/docs.sh +++ b/contrib/ci/jobs/3-docs/docs.sh diff --git a/ci/jobs/3-docs/job.sh b/contrib/ci/jobs/3-docs/job.sh index a72bca4ba..a72bca4ba 100755 --- a/ci/jobs/3-docs/job.sh +++ b/contrib/ci/jobs/3-docs/job.sh diff --git a/ci/jobs/4-deb-package/install-fix.patch b/contrib/ci/jobs/4-deb-package/install-fix.patch index 8334c5a7a..8334c5a7a 100644 --- a/ci/jobs/4-deb-package/install-fix.patch +++ b/contrib/ci/jobs/4-deb-package/install-fix.patch diff --git a/ci/jobs/4-deb-package/job.sh b/contrib/ci/jobs/4-deb-package/job.sh index dc78cdf24..dc78cdf24 100755 --- a/ci/jobs/4-deb-package/job.sh +++ b/contrib/ci/jobs/4-deb-package/job.sh diff --git a/contrib/gana b/contrib/gana -Subproject 27de076550489d6ca0b99822121579e02fee4cf +Subproject 2ccbe6a28c86fb1618d30b3d76d9fd70c95203a diff --git a/contrib/wallet-core b/contrib/wallet-core -Subproject 621dad2c2ec9a2adc52076cebf65891d6764c80 +Subproject 6eca153b329953b703d0517dbd65001715431c6 diff --git a/src/bank-lib/fakebank_common_parser.c b/src/bank-lib/fakebank_common_parser.c index 98b8d6097..cf2dc5a74 100644 --- a/src/bank-lib/fakebank_common_parser.c +++ b/src/bank-lib/fakebank_common_parser.c @@ -112,7 +112,7 @@ TALER_FAKEBANK_common_parse_history_args ( : GNUNET_SYSERR; } if (NULL == start) - ha->start_idx = (d > 0) ? 0 : h->serial_counter; + ha->start_idx = (d > 0) ? 0 : UINT64_MAX; else ha->start_idx = (uint64_t) sval; ha->delta = (int64_t) d; diff --git a/src/bank-lib/fakebank_tbr_get_history.c b/src/bank-lib/fakebank_tbr_get_history.c index 8147d943a..e81e00894 100644 --- a/src/bank-lib/fakebank_tbr_get_history.c +++ b/src/bank-lib/fakebank_tbr_get_history.c @@ -60,6 +60,8 @@ TALER_FAKEBANK_tbr_get_history_incoming ( struct HistoryContext *hc; const struct Transaction *pos; enum GNUNET_GenericReturnValue ret; + bool in_shutdown; + const char *acc_payto_uri; if (NULL == cc) { @@ -82,6 +84,8 @@ TALER_FAKEBANK_tbr_get_history_incoming ( } GNUNET_assert (0 == pthread_mutex_lock (&h->big_lock)); + if (UINT64_MAX == hc->ha.start_idx) + hc->ha.start_idx = h->serial_counter; hc->acc = TALER_FAKEBANK_lookup_account_ (h, account, NULL); @@ -267,12 +271,14 @@ TALER_FAKEBANK_tbr_get_history_incoming ( pthread_mutex_unlock (&h->big_lock)); return MHD_YES; } + in_shutdown = h->in_shutdown; + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); finish: if (0 == json_array_size (hc->history)) { - GNUNET_break (h->in_shutdown || + GNUNET_break (in_shutdown || (! GNUNET_TIME_absolute_is_future (hc->timeout))); return TALER_MHD_reply_static (connection, MHD_HTTP_NO_CONTENT, @@ -289,7 +295,7 @@ finish: MHD_HTTP_OK, GNUNET_JSON_pack_string ( "credit_account", - hc->acc->payto_uri), + acc_payto_uri), GNUNET_JSON_pack_array_steal ( "incoming_transactions", h)); diff --git a/src/bank-lib/fakebank_twg_history.c b/src/bank-lib/fakebank_twg_history.c index 44bae314b..1d70ed127 100644 --- a/src/bank-lib/fakebank_twg_history.c +++ b/src/bank-lib/fakebank_twg_history.c @@ -58,6 +58,8 @@ TALER_FAKEBANK_twg_get_debit_history_ ( struct HistoryContext *hc; struct Transaction *pos; enum GNUNET_GenericReturnValue ret; + bool in_shutdown; + const char *acc_payto_uri; if (NULL == cc) { @@ -80,6 +82,8 @@ TALER_FAKEBANK_twg_get_debit_history_ ( } GNUNET_assert (0 == pthread_mutex_lock (&h->big_lock)); + if (UINT64_MAX == hc->ha.start_idx) + hc->ha.start_idx = h->serial_counter; hc->acc = TALER_FAKEBANK_lookup_account_ (h, account, NULL); @@ -264,12 +268,14 @@ TALER_FAKEBANK_twg_get_debit_history_ ( pthread_mutex_unlock (&h->big_lock)); return MHD_YES; } + in_shutdown = h->in_shutdown; + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); finish: if (0 == json_array_size (hc->history)) { - GNUNET_break (h->in_shutdown || + GNUNET_break (in_shutdown || (! GNUNET_TIME_absolute_is_future (hc->timeout))); return TALER_MHD_reply_static (connection, MHD_HTTP_NO_CONTENT, @@ -286,7 +292,7 @@ finish: MHD_HTTP_OK, GNUNET_JSON_pack_string ( "debit_account", - hc->acc->payto_uri), + acc_payto_uri), GNUNET_JSON_pack_array_steal ( "outgoing_transactions", h)); @@ -305,6 +311,8 @@ TALER_FAKEBANK_twg_get_credit_history_ ( struct HistoryContext *hc; const struct Transaction *pos; enum GNUNET_GenericReturnValue ret; + bool in_shutdown; + const char *acc_payto_uri; if (NULL == cc) { @@ -327,6 +335,8 @@ TALER_FAKEBANK_twg_get_credit_history_ ( } GNUNET_assert (0 == pthread_mutex_lock (&h->big_lock)); + if (UINT64_MAX == hc->ha.start_idx) + hc->ha.start_idx = h->serial_counter; hc->acc = TALER_FAKEBANK_lookup_account_ (h, account, NULL); @@ -491,12 +501,14 @@ TALER_FAKEBANK_twg_get_credit_history_ ( pthread_mutex_unlock (&h->big_lock)); return MHD_YES; } + in_shutdown = h->in_shutdown; + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); finish: if (0 == json_array_size (hc->history)) { - GNUNET_break (h->in_shutdown || + GNUNET_break (in_shutdown || (! GNUNET_TIME_absolute_is_future (hc->timeout))); return TALER_MHD_reply_static (connection, MHD_HTTP_NO_CONTENT, @@ -513,7 +525,7 @@ finish: MHD_HTTP_OK, GNUNET_JSON_pack_string ( "credit_account", - hc->acc->payto_uri), + acc_payto_uri), GNUNET_JSON_pack_array_steal ( "incoming_transactions", h)); diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index 3eb0ba460..1a8d61e70 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -1350,7 +1350,7 @@ upload_auditor_add (const char *exchange_url, const char *err_name; unsigned int err_line; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("auditor_url", + TALER_JSON_spec_web_url ("auditor_url", &auditor_url), GNUNET_JSON_spec_string ("auditor_name", &auditor_name), @@ -1547,10 +1547,10 @@ upload_wire_add (const char *exchange_url, const json_t *credit_restrictions; unsigned int err_line; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("payto_uri", - &payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &payto_uri), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("conversion_url", + TALER_JSON_spec_web_url ("conversion_url", &conversion_url), NULL), GNUNET_JSON_spec_array_const ("debit_restrictions", @@ -1683,8 +1683,8 @@ upload_wire_del (const char *exchange_url, const char *err_name; unsigned int err_line; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("payto_uri", - &payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &payto_uri), GNUNET_JSON_spec_timestamp ("validity_end", &end_time), GNUNET_JSON_spec_fixed_auto ("master_sig", @@ -2012,8 +2012,8 @@ upload_drain (const char *exchange_url, &date), GNUNET_JSON_spec_string ("account_section", &account_section), - GNUNET_JSON_spec_string ("payto_uri", - &payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &payto_uri), GNUNET_JSON_spec_fixed_auto ("master_sig", &master_sig), GNUNET_JSON_spec_end () @@ -2424,7 +2424,7 @@ add_partner (const char *exchange_url, &start_date), GNUNET_JSON_spec_timestamp ("end_date", &end_date), - GNUNET_JSON_spec_string ("partner_base_url", + TALER_JSON_spec_web_url ("partner_base_url", &partner_base_url), GNUNET_JSON_spec_fixed_auto ("master_sig", &master_sig), diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c index 9b9f1cb88..632368ded 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c @@ -597,8 +597,9 @@ TEH_handler_age_withdraw_reveal ( } while(0); GNUNET_JSON_parse_free (spec); - for (unsigned int i = 0; i<actx.num_coins; i++) - TALER_blinded_denom_sig_free (&actx.commitment.denom_sigs[i]); + if (NULL != actx.commitment.denom_sigs) + for (unsigned int i = 0; i<actx.num_coins; i++) + TALER_blinded_denom_sig_free (&actx.commitment.denom_sigs[i]); GNUNET_free (actx.commitment.denom_sigs); GNUNET_free (actx.commitment.denom_pub_hashes); GNUNET_free (actx.commitment.denom_serials); diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c index e688b2ba6..bf43fdbf2 100644 --- a/src/exchange/taler-exchange-httpd_aml-decision.c +++ b/src/exchange/taler-exchange-httpd_aml-decision.c @@ -246,7 +246,6 @@ TEH_handler_post_aml_decision ( struct DecisionContext dc = { .officer_pub = officer_pub }; - uint32_t new_state32; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("officer_sig", &dc.officer_sig), @@ -259,8 +258,8 @@ TEH_handler_post_aml_decision ( &dc.justification), GNUNET_JSON_spec_timestamp ("decision_time", &dc.decision_time), - GNUNET_JSON_spec_uint32 ("new_state", - &new_state32), + TALER_JSON_spec_aml_decision ("new_state", + &dc.new_state), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_array_const ("kyc_requirements", &dc.kyc_requirements), @@ -282,7 +281,6 @@ TEH_handler_post_aml_decision ( return MHD_YES; /* failure */ } } - dc.new_state = (enum TALER_AmlDecisionState) new_state32; TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; if (GNUNET_OK != TALER_officer_aml_decision_verify (dc.justification, diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index 32c39adce..baf2b964d 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -476,8 +476,8 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, const json_t *coins; bool no_refund_deadline = true; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("merchant_payto_uri", - &bd->receiver_wire_account), + TALER_JSON_spec_payto_uri ("merchant_payto_uri", + &bd->receiver_wire_account), GNUNET_JSON_spec_fixed_auto ("wire_salt", &bd->wire_salt), GNUNET_JSON_spec_fixed_auto ("merchant_pub", @@ -523,8 +523,9 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, return MHD_YES; /* failure */ } } - TALER_amount_set_zero (TEH_currency, - &dc.policy_details.accumulated_total); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (TEH_currency, + &dc.policy_details.accumulated_total)); /* validate merchant's wire details (as far as we can) */ { char *emsg; diff --git a/src/exchange/taler-exchange-httpd_management_auditors.c b/src/exchange/taler-exchange-httpd_management_auditors.c index 9c7a5c472..7e0593534 100644 --- a/src/exchange/taler-exchange-httpd_management_auditors.c +++ b/src/exchange/taler-exchange-httpd_management_auditors.c @@ -153,7 +153,7 @@ TEH_handler_management_auditors ( &aac.master_sig), GNUNET_JSON_spec_fixed_auto ("auditor_pub", &aac.auditor_pub), - GNUNET_JSON_spec_string ("auditor_url", + TALER_JSON_spec_web_url ("auditor_url", &aac.auditor_url), GNUNET_JSON_spec_string ("auditor_name", &aac.auditor_name), diff --git a/src/exchange/taler-exchange-httpd_management_drain.c b/src/exchange/taler-exchange-httpd_management_drain.c index 565c292f4..1e490d799 100644 --- a/src/exchange/taler-exchange-httpd_management_drain.c +++ b/src/exchange/taler-exchange-httpd_management_drain.c @@ -124,8 +124,8 @@ TEH_handler_management_post_drain ( struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("debit_account_section", &dc.account_section), - GNUNET_JSON_spec_string ("credit_payto_uri", - &dc.payto_uri), + TALER_JSON_spec_payto_uri ("credit_payto_uri", + &dc.payto_uri), GNUNET_JSON_spec_fixed_auto ("wtid", &dc.wtid), GNUNET_JSON_spec_fixed_auto ("master_sig", diff --git a/src/exchange/taler-exchange-httpd_management_partners.c b/src/exchange/taler-exchange-httpd_management_partners.c index e336d24ed..fc8a4207d 100644 --- a/src/exchange/taler-exchange-httpd_management_partners.c +++ b/src/exchange/taler-exchange-httpd_management_partners.c @@ -48,7 +48,7 @@ TEH_handler_management_partners ( &partner_pub), GNUNET_JSON_spec_fixed_auto ("master_sig", &master_sig), - GNUNET_JSON_spec_string ("partner_base_url", + TALER_JSON_spec_web_url ("partner_base_url", &partner_base_url), TALER_JSON_spec_amount ("wad_fee", TEH_currency, diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c index 0cf8ab727..f91f24c41 100644 --- a/src/exchange/taler-exchange-httpd_management_post_keys.c +++ b/src/exchange/taler-exchange-httpd_management_post_keys.c @@ -271,7 +271,7 @@ TEH_handler_management_post_keys ( struct MHD_Connection *connection, const json_t *root) { - struct AddKeysContext akc; + struct AddKeysContext akc = { 0 }; const json_t *denom_sigs; const json_t *signkey_sigs; struct GNUNET_JSON_Specification spec[] = { diff --git a/src/exchange/taler-exchange-httpd_management_wire_disable.c b/src/exchange/taler-exchange-httpd_management_wire_disable.c index 5bca5736b..d3015fb68 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_disable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_disable.c @@ -143,8 +143,8 @@ TEH_handler_management_post_wire_disable ( struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("master_sig_del", &awc.master_sig), - GNUNET_JSON_spec_string ("payto_uri", - &awc.payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &awc.payto_uri), GNUNET_JSON_spec_timestamp ("validity_end", &awc.validity_end), GNUNET_JSON_spec_end () diff --git a/src/exchange/taler-exchange-httpd_management_wire_enable.c b/src/exchange/taler-exchange-httpd_management_wire_enable.c index b0db390a2..ca5b4ee78 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_enable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_enable.c @@ -170,10 +170,10 @@ TEH_handler_management_post_wire ( &awc.master_sig_wire), GNUNET_JSON_spec_fixed_auto ("master_sig_add", &awc.master_sig_add), - GNUNET_JSON_spec_string ("payto_uri", - &awc.payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &awc.payto_uri), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("conversion_url", + TALER_JSON_spec_web_url ("conversion_url", &awc.conversion_url), NULL), GNUNET_JSON_spec_array_const ("credit_restrictions", diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c b/src/exchange/taler-exchange-httpd_purses_merge.c index d1edc49b4..5b66254f5 100644 --- a/src/exchange/taler-exchange-httpd_purses_merge.c +++ b/src/exchange/taler-exchange-httpd_purses_merge.c @@ -421,8 +421,8 @@ TEH_handler_purses_merge ( .exchange_timestamp = GNUNET_TIME_timestamp_get () }; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("payto_uri", - &pcc.payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &pcc.payto_uri), GNUNET_JSON_spec_fixed_auto ("reserve_sig", &pcc.reserve_sig), GNUNET_JSON_spec_fixed_auto ("merge_sig", diff --git a/src/exchange/taler-exchange-httpd_reserves_close.c b/src/exchange/taler-exchange-httpd_reserves_close.c index bcde80881..bbf234428 100644 --- a/src/exchange/taler-exchange-httpd_reserves_close.c +++ b/src/exchange/taler-exchange-httpd_reserves_close.c @@ -367,8 +367,8 @@ TEH_handler_reserves_close (struct TEH_RequestContext *rc, GNUNET_JSON_spec_timestamp ("request_timestamp", &rcc.timestamp), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("payto_uri", - &rcc.payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &rcc.payto_uri), NULL), GNUNET_JSON_spec_fixed_auto ("reserve_sig", &rcc.reserve_sig), diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 65a28d715..cecd0562e 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -69,8 +69,12 @@ enum TALER_AmlDecisionState /** * An AML decision has concluded that the funds must be frozen. */ - TALER_AML_FROZEN = 2 + TALER_AML_FROZEN = 2, + /** + * Maximum allowed numeric value for AML status. + */ + TALER_AML_MAX = 2 }; diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index d2bf918da..7b9b1dd41 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -2075,7 +2075,7 @@ struct TALER_EXCHANGE_ReserveHistoryEntry struct { /** - * Receiver account information for the outgoing wire transfer. + * Receiver account information for the outgoing wire transfer as a payto://-URI. */ const char *receiver_account_details; diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 1a1466700..dc8061705 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -355,6 +355,98 @@ struct GNUNET_JSON_Specification TALER_JSON_spec_denom_pub (const char *field, struct TALER_DenominationPublicKey *pk); + +/** + * Generate line in parser specification for error codes. + * + * @param field name of the field + * @param[out] ec error code to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_ec (const char *field, + enum TALER_ErrorCode *ec); + + +/** + * Generate line in parser specification for + * HTTP/HTTPS URLs. + * + * @param field name of the field + * @param[out] url web URL to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_web_url (const char *field, + const char **url); + + +/** + * Generate line in parser specification for + * "payto://" URIs. + * + * @param field name of the field + * @param[out] payto_uri RFC 8905 URI to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_payto_uri (const char *field, + const char **payto_uri); + + +/** + * Generate line in parser specification for AML decision states. + * + * @param field name of the field + * @param[out] aml_state AML state to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_aml_decision (const char *field, + enum TALER_AmlDecisionState *aml_state); + + +/** + * Representation of a protocol version. + */ +struct TALER_JSON_ProtocolVersion +{ + /** + * Current version of the protocol. + */ + unsigned int current; + + /** + * Implementation revision for the @e current + * version. + */ + unsigned int revision; + + /** + * Number of protocol versions this @e revision is + * backwards-compatible with. Subtract this number + * from @a current to get the minimum protocol version + * required from the client. + */ + unsigned int age; +}; + + +/** + * Generate line in parser specification for protocol + * versions (``/config``). The field must be a string + * encoding the version as "$CURRENT:$REVISION:$AGE". + * + * @param field name of the field (usually "version") + * @param[out] current protocol current to initialize + * @param[out] revision protocol revision to initialize + * @param[out] age protocol age to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_version (const char *field, + struct TALER_JSON_ProtocolVersion *ver); + /** * Generate a parser specification for a denomination public key of a given * cipher. @@ -365,10 +457,10 @@ TALER_JSON_spec_denom_pub (const char *field, * @return corresponding field spec */ struct GNUNET_JSON_Specification -TALER_JSON_spec_denom_pub_cipher (const char *field, - enum GNUNET_CRYPTO_BlindSignatureAlgorithm - cipher, - struct TALER_DenominationPublicKey *pk); +TALER_JSON_spec_denom_pub_cipher ( + const char *field, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, + struct TALER_DenominationPublicKey *pk); /** diff --git a/src/include/taler_util.h b/src/include/taler_util.h index 19dc84fc0..7c2cc6880 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -367,6 +367,17 @@ TALER_url_valid_charset (const char *url); /** + * Test if the URL is a valid "http" (or "https") + * URL (includes test for #TALER_url_valid_charset()). + * + * @param url a string to test if it could be a valid URL + * @return true if @a url is well-formed + */ +bool +TALER_is_web_url (const char *url); + + +/** * Check if @a lang matches the @a language_pattern, and if so with * which preference. * See also: https://tools.ietf.org/html/rfc7231#section-5.3.1 diff --git a/src/json/json_helper.c b/src/json/json_helper.c index fd2a8d272..0628282ca 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -1426,4 +1426,250 @@ TALER_JSON_spec_i18n_str (const char *name, } +/** + * Parse given JSON object with Taler error code. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_ec (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + enum TALER_ErrorCode *ec = spec->ptr; + json_int_t num; + + (void) cls; + if (! json_is_integer (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + num = json_integer_value (root); + if (num < 0) + { + GNUNET_break_op (0); + *ec = TALER_EC_INVALID; + return GNUNET_SYSERR; + } + *ec = (enum TALER_ErrorCode) num; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_ec (const char *field, + enum TALER_ErrorCode *ec) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_ec, + .field = field, + .ptr = ec + }; + + *ec = TALER_EC_NONE; + return ret; +} + + +/** + * Parse given JSON object with AML decision. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_aml_decision (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + enum TALER_AmlDecisionState *aml = spec->ptr; + json_int_t num; + + (void) cls; + if (! json_is_integer (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + num = json_integer_value (root); + if ( (num > TALER_AML_MAX) || + (num < 0) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + *aml = (enum TALER_AmlDecisionState) num; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_aml_decision (const char *field, + enum TALER_AmlDecisionState *aml_state) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_aml_decision, + .field = field, + .ptr = aml_state + }; + + return ret; +} + + +/** + * Parse given JSON object to web URL. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_web_url (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + const char *str; + + (void) cls; + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (! TALER_is_web_url (str)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + *(const char **) spec->ptr = str; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_web_url (const char *field, + const char **url) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_web_url, + .field = field, + .ptr = url + }; + + *url = NULL; + return ret; +} + + +/** + * Parse given JSON object to payto:// URI. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_payto_uri (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + const char *str; + char *err; + + (void) cls; + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + err = TALER_payto_validate (str); + if (NULL != err) + { + GNUNET_break_op (0); + GNUNET_free (err); + return GNUNET_SYSERR; + } + *(const char **) spec->ptr = str; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_payto_uri (const char *field, + const char **payto_uri) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_payto_uri, + .field = field, + .ptr = payto_uri + }; + + *payto_uri = NULL; + return ret; +} + + +/** + * Parse given JSON object with protocol version. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_protocol_version (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_JSON_ProtocolVersion *pv = spec->ptr; + const char *ver; + char dummy; + + (void) cls; + if (! json_is_string (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + ver = json_string_value (root); + if (3 != sscanf (ver, + "%u:%u:%u%c", + &pv->current, + &pv->revision, + &pv->age, + &dummy)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_version (const char *field, + struct TALER_JSON_ProtocolVersion *ver) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_protocol_version, + .field = field, + .ptr = ver + }; + + return ret; +} + + /* end of json/json_helper.c */ diff --git a/src/lib/auditor_api_exchanges.c b/src/lib/auditor_api_exchanges.c index 897dfe60f..1988c2faf 100644 --- a/src/lib/auditor_api_exchanges.c +++ b/src/lib/auditor_api_exchanges.c @@ -125,7 +125,7 @@ handle_exchanges_finished (void *cls, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("master_pub", &ei[i].master_pub), - GNUNET_JSON_spec_string ("exchange_url", + TALER_JSON_spec_web_url ("exchange_url", &ei[i].exchange_url), GNUNET_JSON_spec_end () }; diff --git a/src/lib/auditor_api_get_config.c b/src/lib/auditor_api_get_config.c index c9f366568..5d0b4db81 100644 --- a/src/lib/auditor_api_get_config.c +++ b/src/lib/auditor_api_get_config.c @@ -104,12 +104,11 @@ decode_config_json (const json_t *resp_obj, struct TALER_AUDITOR_ConfigInformation *vi, enum TALER_AUDITOR_VersionCompatibility *vc) { - unsigned int age; - unsigned int revision; - unsigned int current; - char dummy; + struct TALER_JSON_ProtocolVersion pv; const char *ver; struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_version ("version", + &pv), GNUNET_JSON_spec_string ("version", &ver), GNUNET_JSON_spec_fixed_auto ("auditor_public_key", @@ -131,28 +130,18 @@ decode_config_json (const json_t *resp_obj, GNUNET_break_op (0); return TALER_EC_GENERIC_JSON_INVALID; } - if (3 != sscanf (ver, - "%u:%u:%u%c", - ¤t, - &revision, - &age, - &dummy)) - { - GNUNET_break_op (0); - return TALER_EC_GENERIC_VERSION_MALFORMED; - } vi->version = ver; *vc = TALER_AUDITOR_VC_MATCH; - if (TALER_PROTOCOL_CURRENT < current) + if (TALER_PROTOCOL_CURRENT < pv.current) { *vc |= TALER_AUDITOR_VC_NEWER; - if (TALER_PROTOCOL_CURRENT < current - age) + if (TALER_PROTOCOL_CURRENT < pv.current - pv.age) *vc |= TALER_AUDITOR_VC_INCOMPATIBLE; } - if (TALER_PROTOCOL_CURRENT > current) + if (TALER_PROTOCOL_CURRENT > pv.current) { *vc |= TALER_AUDITOR_VC_OLDER; - if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current) + if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > pv.current) *vc |= TALER_AUDITOR_VC_INCOMPATIBLE; } return TALER_EC_NONE; diff --git a/src/lib/exchange_api_batch_deposit.c b/src/lib/exchange_api_batch_deposit.c index f9d505dcd..56b9b11e3 100644 --- a/src/lib/exchange_api_batch_deposit.c +++ b/src/lib/exchange_api_batch_deposit.c @@ -360,7 +360,7 @@ handle_deposit_finished (void *cls, GNUNET_JSON_spec_fixed_auto ("exchange_pub", &dh->exchange_pub), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("transaction_base_url", + TALER_JSON_spec_web_url ("transaction_base_url", &dr->details.ok.transaction_base_url), NULL), GNUNET_JSON_spec_timestamp ("exchange_timestamp", diff --git a/src/lib/exchange_api_coins_history.c b/src/lib/exchange_api_coins_history.c index 875a5b57b..6981fad5a 100644 --- a/src/lib/exchange_api_coins_history.c +++ b/src/lib/exchange_api_coins_history.c @@ -576,7 +576,7 @@ help_purse_deposit (struct CoinHistoryParseContext *pc, GNUNET_JSON_spec_fixed_auto ("h_age_commitment", &rh->details.purse_deposit.phac), NULL), - GNUNET_JSON_spec_string ("exchange_base_url", + TALER_JSON_spec_web_url ("exchange_base_url", &rh->details.purse_deposit.exchange_base_url), GNUNET_JSON_spec_bool ("refunded", &rh->details.purse_deposit.refunded), @@ -1093,6 +1093,7 @@ TALER_EXCHANGE_coins_history ( if (NULL == job_headers) { GNUNET_break (0); + curl_easy_cleanup (eh); return NULL; } } diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 4846e1188..239632656 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -119,7 +119,7 @@ TALER_EXCHANGE_check_purse_merge_conflict_ ( struct TALER_ReservePublicKeyP reserve_pub; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("partner_url", + TALER_JSON_spec_web_url ("partner_url", &partner_url), NULL), GNUNET_JSON_spec_timestamp ("merge_timestamp", @@ -191,7 +191,7 @@ TALER_EXCHANGE_check_purse_coin_conflict_ ( GNUNET_JSON_spec_fixed_auto ("coin_pub", coin_pub), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("partner_url", + TALER_JSON_spec_web_url ("partner_url", &partner_url), NULL), TALER_JSON_spec_amount_any ("amount", @@ -515,10 +515,10 @@ TALER_EXCHANGE_parse_accounts ( const json_t *credit_restrictions; const json_t *debit_restrictions; struct GNUNET_JSON_Specification spec_account[] = { - GNUNET_JSON_spec_string ("payto_uri", - &payto_uri), + TALER_JSON_spec_payto_uri ("payto_uri", + &payto_uri), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("conversion_url", + TALER_JSON_spec_web_url ("conversion_url", &conversion_url), NULL), GNUNET_JSON_spec_array_const ("credit_restrictions", @@ -542,18 +542,6 @@ TALER_EXCHANGE_parse_accounts ( GNUNET_break_op (0); return GNUNET_SYSERR; } - { - char *err; - - err = TALER_payto_validate (payto_uri); - if (NULL != err) - { - GNUNET_break_op (0); - GNUNET_free (err); - return GNUNET_SYSERR; - } - } - if ( (NULL != master_pub) && (GNUNET_OK != TALER_exchange_wire_signature_check ( diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index 8b145dabd..ee5f9dc68 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -177,7 +177,6 @@ handle_deposit_wtid_finished (void *cls, { /* Transaction known, but not executed yet */ bool no_legi = false; - uint32_t state32; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ("execution_time", &dr.details.accepted.execution_time), @@ -185,8 +184,8 @@ handle_deposit_wtid_finished (void *cls, GNUNET_JSON_spec_uint64 ("requirement_row", &dr.details.accepted.requirement_row), &no_legi), - GNUNET_JSON_spec_uint32 ("aml_decision", - &state32), + TALER_JSON_spec_aml_decision ("aml_decision", + &dr.details.accepted.aml_decision), GNUNET_JSON_spec_bool ("kyc_ok", &dr.details.accepted.kyc_ok), GNUNET_JSON_spec_end () @@ -202,8 +201,6 @@ handle_deposit_wtid_finished (void *cls, dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - dr.details.accepted.aml_decision - = (enum TALER_AmlDecisionState) state32; if (no_legi) dr.details.accepted.requirement_row = 0; dwh->cb (dwh->cb_cls, diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 410c01245..ab3c387df 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -550,7 +550,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("auditor_pub", &auditor->auditor_pub), - GNUNET_JSON_spec_string ("auditor_url", + TALER_JSON_spec_web_url ("auditor_url", &auditor_url), GNUNET_JSON_spec_array_const ("denomination_keys", &keys), @@ -791,14 +791,10 @@ decode_keys_json (const json_t *resp_obj, #endif /* check the version first */ { - const char *ver; - unsigned int age; - unsigned int revision; - unsigned int current; - char dummy; + struct TALER_JSON_ProtocolVersion pv; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("version", - &ver), + TALER_JSON_spec_version ("version", + &pv), GNUNET_JSON_spec_end () }; @@ -810,33 +806,23 @@ decode_keys_json (const json_t *resp_obj, GNUNET_break_op (0); return GNUNET_SYSERR; } - if (3 != sscanf (ver, - "%u:%u:%u%c", - ¤t, - &revision, - &age, - &dummy)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } *vc = TALER_EXCHANGE_VC_MATCH; - if (EXCHANGE_PROTOCOL_CURRENT < current) + if (EXCHANGE_PROTOCOL_CURRENT < pv.current) { *vc |= TALER_EXCHANGE_VC_NEWER; - if (EXCHANGE_PROTOCOL_CURRENT < current - age) + if (EXCHANGE_PROTOCOL_CURRENT < pv.current - pv.age) *vc |= TALER_EXCHANGE_VC_INCOMPATIBLE; } - if (EXCHANGE_PROTOCOL_CURRENT > current) + if (EXCHANGE_PROTOCOL_CURRENT > pv.current) { *vc |= TALER_EXCHANGE_VC_OLDER; - if (EXCHANGE_PROTOCOL_CURRENT - EXCHANGE_PROTOCOL_AGE > current) + if (EXCHANGE_PROTOCOL_CURRENT - EXCHANGE_PROTOCOL_AGE > pv.current) *vc |= TALER_EXCHANGE_VC_INCOMPATIBLE; } - key_data->version = GNUNET_strdup (ver); } { + const char *ver; const char *currency; const char *asset_type; struct GNUNET_JSON_Specification mspec[] = { @@ -901,6 +887,8 @@ decode_keys_json (const json_t *resp_obj, "extensions_sig", &key_data->extensions_sig), &no_signature), + GNUNET_JSON_spec_string ("version", + &ver), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_array_const ( "wallet_balance_limit_without_kyc", @@ -946,6 +934,7 @@ decode_keys_json (const json_t *resp_obj, } key_data->currency = GNUNET_strdup (currency); + key_data->version = GNUNET_strdup (ver); key_data->asset_type = GNUNET_strdup (asset_type); if (! no_extensions) key_data->extensions = json_incref ((json_t *) manifests); @@ -1896,7 +1885,7 @@ TALER_EXCHANGE_keys_from_json (const json_t *j) &version), GNUNET_JSON_spec_object_const ("keys", &jkeys), - GNUNET_JSON_spec_string ("exchange_url", + TALER_JSON_spec_web_url ("exchange_url", &url), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("expire", diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c index 373dd89a7..5d3b3792b 100644 --- a/src/lib/exchange_api_kyc_check.c +++ b/src/lib/exchange_api_kyc_check.c @@ -97,7 +97,6 @@ handle_kyc_check_finished (void *cls, case MHD_HTTP_OK: { const json_t *kyc_details; - uint32_t status; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", &ks.details.ok.exchange_sig), @@ -107,8 +106,8 @@ handle_kyc_check_finished (void *cls, &ks.details.ok.timestamp), GNUNET_JSON_spec_object_const ("kyc_details", &kyc_details), - GNUNET_JSON_spec_uint32 ("aml_status", - &status), + TALER_JSON_spec_aml_decision ("aml_status", + &ks.details.ok.aml_status), GNUNET_JSON_spec_end () }; @@ -123,8 +122,6 @@ handle_kyc_check_finished (void *cls, break; } ks.details.ok.kyc_details = kyc_details; - ks.details.ok.aml_status - = (enum TALER_AmlDecisionState) status; if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (kch->keys, &ks.details.ok.exchange_pub)) @@ -158,12 +155,11 @@ handle_kyc_check_finished (void *cls, } case MHD_HTTP_ACCEPTED: { - uint32_t status; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("kyc_url", + TALER_JSON_spec_web_url ("kyc_url", &ks.details.accepted.kyc_url), - GNUNET_JSON_spec_uint32 ("aml_status", - &status), + TALER_JSON_spec_aml_decision ("aml_status", + &ks.details.accepted.aml_status), GNUNET_JSON_spec_end () }; @@ -177,8 +173,6 @@ handle_kyc_check_finished (void *cls, ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - ks.details.accepted.aml_status - = (enum TALER_AmlDecisionState) status; kch->cb (kch->cb_cls, &ks); GNUNET_JSON_parse_free (spec); @@ -200,10 +194,10 @@ handle_kyc_check_finished (void *cls, break; case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: { - uint32_t status; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_uint32 ("aml_status", - &status), + TALER_JSON_spec_aml_decision ( + "aml_status", + &ks.details.unavailable_for_legal_reasons.aml_status), GNUNET_JSON_spec_end () }; @@ -217,8 +211,6 @@ handle_kyc_check_finished (void *cls, ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - ks.details.unavailable_for_legal_reasons.aml_status - = (enum TALER_AmlDecisionState) status; kch->cb (kch->cb_cls, &ks); GNUNET_JSON_parse_free (spec); diff --git a/src/lib/exchange_api_lookup_aml_decision.c b/src/lib/exchange_api_lookup_aml_decision.c index 01e98213b..501b9d185 100644 --- a/src/lib/exchange_api_lookup_aml_decision.c +++ b/src/lib/exchange_api_lookup_aml_decision.c @@ -80,7 +80,6 @@ parse_aml_history (const json_t *aml_history, json_array_foreach (aml_history, idx, obj) { struct TALER_EXCHANGE_AmlDecisionDetail *aml = &aml_history_ar[idx]; - uint32_t state32; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ("decision_time", &aml->decision_time), @@ -88,8 +87,8 @@ parse_aml_history (const json_t *aml_history, &aml->justification), TALER_JSON_spec_amount_any ("new_threshold", &aml->new_threshold), - GNUNET_JSON_spec_uint32 ("new_state", - &state32), + TALER_JSON_spec_aml_decision ("new_state", + &aml->new_state), GNUNET_JSON_spec_fixed_auto ("decider_pub", &aml->decider_pub), GNUNET_JSON_spec_end () @@ -104,7 +103,6 @@ parse_aml_history (const json_t *aml_history, GNUNET_break_op (0); return GNUNET_SYSERR; } - aml->new_state = (enum TALER_AmlDecisionState) state32; } return GNUNET_OK; } diff --git a/src/lib/exchange_api_lookup_aml_decisions.c b/src/lib/exchange_api_lookup_aml_decisions.c index 22222b1e4..bb3c18b68 100644 --- a/src/lib/exchange_api_lookup_aml_decisions.c +++ b/src/lib/exchange_api_lookup_aml_decisions.c @@ -80,12 +80,11 @@ parse_aml_decisions (const json_t *decisions, json_array_foreach (decisions, idx, obj) { struct TALER_EXCHANGE_AmlDecisionSummary *decision = &decision_ar[idx]; - uint32_t state32; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("h_payto", &decision->h_payto), - GNUNET_JSON_spec_uint32 ("current_state", - &state32), + TALER_JSON_spec_aml_decision ("current_state", + &decision->current_state), TALER_JSON_spec_amount_any ("threshold", &decision->threshold), GNUNET_JSON_spec_uint64 ("rowid", @@ -102,7 +101,6 @@ parse_aml_decisions (const json_t *decisions, GNUNET_break_op (0); return GNUNET_SYSERR; } - decision->current_state = (enum TALER_AmlDecisionState) state32; } return GNUNET_OK; } diff --git a/src/lib/exchange_api_reserves_history.c b/src/lib/exchange_api_reserves_history.c index 7b8eb95e6..0654ad837 100644 --- a/src/lib/exchange_api_reserves_history.c +++ b/src/lib/exchange_api_reserves_history.c @@ -148,7 +148,7 @@ parse_credit (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, struct HistoryParseContext *uc, const json_t *transaction) { - const char *wire_url; + const char *wire_uri; uint64_t wire_reference; struct GNUNET_TIME_Timestamp timestamp; struct GNUNET_JSON_Specification withdraw_spec[] = { @@ -156,8 +156,8 @@ parse_credit (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, &wire_reference), GNUNET_JSON_spec_timestamp ("timestamp", ×tamp), - GNUNET_JSON_spec_string ("sender_account_url", - &wire_url), + TALER_JSON_spec_payto_uri ("sender_account_url", + &wire_uri), GNUNET_JSON_spec_end () }; @@ -179,7 +179,7 @@ parse_credit (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, GNUNET_break_op (0); return GNUNET_SYSERR; } - rh->details.in_details.sender_url = GNUNET_strdup (wire_url); + rh->details.in_details.sender_url = GNUNET_strdup (wire_uri); rh->details.in_details.wire_reference = wire_reference; rh->details.in_details.timestamp = timestamp; return GNUNET_OK; @@ -379,7 +379,7 @@ parse_closing (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, { const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification closing_spec[] = { - GNUNET_JSON_spec_string ( + TALER_JSON_spec_payto_uri ( "receiver_account_details", &rh->details.close_details.receiver_account_details), GNUNET_JSON_spec_fixed_auto ("wtid", diff --git a/src/lib/test_stefan.c b/src/lib/test_stefan.c index 838cca769..4f7add593 100644 --- a/src/lib/test_stefan.c +++ b/src/lib/test_stefan.c @@ -92,7 +92,7 @@ main (int argc, "INFO", NULL); GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("MAGIC:0.13", + TALER_string_to_amount ("MAGIC:0.00001", &dk.value)); GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("MAGIC:1", diff --git a/src/testing/testing_api_cmd_refund.c b/src/testing/testing_api_cmd_refund.c index 578bee46b..29b68ef08 100644 --- a/src/testing/testing_api_cmd_refund.c +++ b/src/testing/testing_api_cmd_refund.c @@ -97,6 +97,34 @@ refund_cb (void *cls, rs->expected_response_code); return; } + if (MHD_HTTP_OK == hr->http_status) + { + struct TALER_Amount refund_amount; + + if (GNUNET_OK != + TALER_string_to_amount (rs->refund_amount, + &refund_amount)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse amount `%s'\n", + rs->refund_amount); + TALER_TESTING_interpreter_fail (rs->is); + return; + } + if (0 > + TALER_amount_subtract (&rs->che.amount, + &refund_amount, + &rs->che.details.refund.refund_fee)) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to subtract %s from %s\n", + TALER_amount2s (&rs->che.details.refund.refund_fee), + rs->refund_amount); + TALER_TESTING_interpreter_fail (rs->is); + return; + } + } TALER_TESTING_interpreter_next (rs->is); } @@ -187,9 +215,6 @@ refund_run (void *cls, &rs->che.details.refund.merchant_pub.eddsa_pub); rs->che.details.refund.refund_fee = denom_pub->fees.refund; rs->che.details.refund.sig_amount = refund_amount; - TALER_amount_subtract (&rs->che.amount, - &refund_amount, - &rs->che.details.refund.refund_fee); rs->che.details.refund.rtransaction_id = rs->refund_transaction_id; TALER_merchant_refund_sign (&rs->coin, &h_contract_terms, diff --git a/src/testing/testing_api_twister_helpers.c b/src/testing/testing_api_twister_helpers.c index fef631e50..68fbf0082 100644 --- a/src/testing/testing_api_twister_helpers.c +++ b/src/testing/testing_api_twister_helpers.c @@ -131,7 +131,9 @@ TALER_TWISTER_run_twister (const char *config_filename) &code)) { GNUNET_OS_process_destroy (client_proc); - GNUNET_OS_process_kill (proc, SIGTERM); + GNUNET_break (0 == + GNUNET_OS_process_kill (proc, + SIGTERM)); GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); TWISTER_FAIL (); @@ -142,7 +144,9 @@ TALER_TWISTER_run_twister (const char *config_filename) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to check twister works.\n"); GNUNET_OS_process_destroy (client_proc); - GNUNET_OS_process_kill (proc, SIGTERM); + GNUNET_break (0 == + GNUNET_OS_process_kill (proc, + SIGTERM)); GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); TWISTER_FAIL (); @@ -153,7 +157,9 @@ TALER_TWISTER_run_twister (const char *config_filename) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected error running `taler-twister'!\n"); GNUNET_OS_process_destroy (client_proc); - GNUNET_OS_process_kill (proc, SIGTERM); + GNUNET_break (0 == + GNUNET_OS_process_kill (proc, + SIGTERM)); GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); TWISTER_FAIL (); diff --git a/src/util/config.c b/src/util/config.c index 205670431..1342b53b9 100644 --- a/src/util/config.c +++ b/src/util/config.c @@ -259,6 +259,9 @@ parse_currencies_cb (void *cls, memset (cspec->currency, 0, sizeof (cspec->currency)); + /* Already checked in TALER_check_currency(), repeated here + just to make static analysis happy */ + GNUNET_assert (strlen (str) < TALER_CURRENCY_LEN); strcpy (cspec->currency, str); GNUNET_free (str); diff --git a/src/util/taler-exchange-secmod-eddsa.c b/src/util/taler-exchange-secmod-eddsa.c index 3b78e71df..f7a9702e6 100644 --- a/src/util/taler-exchange-secmod-eddsa.c +++ b/src/util/taler-exchange-secmod-eddsa.c @@ -584,11 +584,11 @@ eddsa_client_init (struct TES_Client *client) static enum GNUNET_GenericReturnValue eddsa_update_client_keys (struct TES_Client *client) { + GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updating client %p to generation %llu\n", client, (unsigned long long) key_gen); - GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); for (struct Key *key = keys_head; NULL != key; key = key->next) diff --git a/src/util/url.c b/src/util/url.c index 1ac197551..73f61dee8 100644 --- a/src/util/url.c +++ b/src/util/url.c @@ -332,4 +332,20 @@ TALER_url_valid_charset (const char *url) } +bool +TALER_is_web_url (const char *url) +{ + if ( (0 != strncasecmp (url, + "https://", + strlen ("https://"))) && + (0 != strncasecmp (url, + "http://", + strlen ("http://"))) ) + return false; + if (! TALER_url_valid_charset (url) ) + return false; + return true; +} + + /* end of url.c */ |