diff --git a/contrib/gana b/contrib/gana index bd4e73b2e..5cfe18c5b 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit bd4e73b2ed06269fdee42eaad21acb5be8be9302 +Subproject commit 5cfe18c5bbfd404a5f7cf27a78577c881ddb9ebd diff --git a/src/auditor/taler-helper-auditor-wire.c b/src/auditor/taler-helper-auditor-wire.c index e3e3764a7..8615c439e 100644 --- a/src/auditor/taler-helper-auditor-wire.c +++ b/src/auditor/taler-helper-auditor-wire.c @@ -1483,10 +1483,10 @@ history_debit_cb (void *cls, switch (dhr->http_status) { case MHD_HTTP_OK: - for (unsigned int i = 0; idetails.success.details_length; i++) + for (unsigned int i = 0; idetails.ok.details_length; i++) { const struct TALER_BANK_DebitDetails *dd - = &dhr->details.success.details[i]; + = &dhr->details.ok.details[i]; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Analyzing bank DEBIT at %s of %s with WTID %s\n", GNUNET_TIME_timestamp2s (dd->execution_date), @@ -1978,10 +1978,10 @@ history_credit_cb (void *cls, switch (chr->http_status) { case MHD_HTTP_OK: - for (unsigned int i = 0; idetails.success.details_length; i++) + for (unsigned int i = 0; idetails.ok.details_length; i++) { const struct TALER_BANK_CreditDetails *cd - = &chr->details.success.details[i]; + = &chr->details.ok.details[i]; if (! analyze_credit (wa, cd)) diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c index 4842de969..14ddcd729 100644 --- a/src/bank-lib/bank_api_credit.c +++ b/src/bank-lib/bank_api_credit.c @@ -131,8 +131,8 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh, return GNUNET_SYSERR; } } - chr.details.success.details_length = len; - chr.details.success.details = cd; + chr.details.ok.details_length = len; + chr.details.ok.details = cd; hh->hcb (hh->hcb_cls, &chr); } diff --git a/src/bank-lib/bank_api_debit.c b/src/bank-lib/bank_api_debit.c index bd9b11941..e40156ce7 100644 --- a/src/bank-lib/bank_api_debit.c +++ b/src/bank-lib/bank_api_debit.c @@ -133,8 +133,8 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle *hh, return GNUNET_SYSERR; } } - dhr.details.success.details_length = len; - dhr.details.success.details = dd; + dhr.details.ok.details_length = len; + dhr.details.ok.details = dd; hh->hcb (hh->hcb_cls, &dhr); } diff --git a/src/bank-lib/taler-exchange-wire-gateway-client.c b/src/bank-lib/taler-exchange-wire-gateway-client.c index 5bfd9311d..a972bcfd2 100644 --- a/src/bank-lib/taler-exchange-wire-gateway-client.c +++ b/src/bank-lib/taler-exchange-wire-gateway-client.c @@ -179,10 +179,10 @@ credit_history_cb (void *cls, global_ret = 0; break; case MHD_HTTP_OK: - for (unsigned int i = 0; idetails.success.details_length; i++) + for (unsigned int i = 0; idetails.ok.details_length; i++) { const struct TALER_BANK_CreditDetails *cd = - &reply->details.success.details[i]; + &reply->details.ok.details[i]; /* If credit/debit accounts were specified, use as a filter */ if ( (NULL != credit_account) && @@ -279,10 +279,10 @@ debit_history_cb (void *cls, global_ret = 0; break; case MHD_HTTP_OK: - for (unsigned int i = 0; idetails.success.details_length; i++) + for (unsigned int i = 0; idetails.ok.details_length; i++) { const struct TALER_BANK_DebitDetails *dd = - &reply->details.success.details[i]; + &reply->details.ok.details[i]; /* If credit/debit accounts were specified, use as a filter */ if ( (NULL != credit_account) && diff --git a/src/exchange-tools/taler-auditor-offline.c b/src/exchange-tools/taler-auditor-offline.c index 53135d9fa..f239c11a9 100644 --- a/src/exchange-tools/taler-auditor-offline.c +++ b/src/exchange-tools/taler-auditor-offline.c @@ -644,26 +644,19 @@ do_upload (char *const *args) * a particular exchange and what keys the exchange is using. * * @param cls closure with the `char **` remaining args - * @param hr HTTP response data - * @param keys information about the various keys used - * by the exchange, NULL if /keys failed - * @param compat protocol compatibility information + * @param kr response data */ static void keys_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_Keys *keys, - enum TALER_EXCHANGE_VersionCompatibility compat) + const struct TALER_EXCHANGE_KeysResponse *kr) { char *const *args = cls; - (void) keys; - (void) compat; - switch (hr->http_status) + switch (kr->hr.http_status) { case MHD_HTTP_OK: - if (! json_is_object (hr->reply)) + if (! json_is_object (kr->hr.reply)) { GNUNET_break (0); TALER_EXCHANGE_disconnect (exchange); @@ -676,9 +669,9 @@ keys_cb ( default: fprintf (stderr, "Failed to download keys: %s (HTTP status: %u/%u)\n", - hr->hint, - hr->http_status, - (unsigned int) hr->ec); + kr->hr.hint, + kr->hr.http_status, + (unsigned int) kr->hr.ec); TALER_EXCHANGE_disconnect (exchange); exchange = NULL; test_shutdown (); @@ -689,7 +682,7 @@ keys_cb ( GNUNET_JSON_pack_string ("operation", OP_INPUT_KEYS), GNUNET_JSON_pack_object_incref ("arguments", - (json_t *) hr->reply)); + (json_t *) kr->hr.reply)); if (NULL == args[0]) { json_dumpf (in, diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index 660864b77..ec48ec831 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -1119,14 +1119,15 @@ load_offline_key (int do_create) * Function called with information about the post revocation operation result. * * @param cls closure with a `struct DenomRevocationRequest` - * @param hr HTTP response data + * @param dr response data */ static void denom_revocation_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *dr) { struct DenomRevocationRequest *drr = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &dr->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -1208,14 +1209,15 @@ upload_denom_revocation (const char *exchange_url, * Function called with information about the post revocation operation result. * * @param cls closure with a `struct SignkeyRevocationRequest` - * @param hr HTTP response data + * @param sr response data */ static void signkey_revocation_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *sr) { struct SignkeyRevocationRequest *srr = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &sr->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -1489,13 +1491,14 @@ upload_auditor_del (const char *exchange_url, * Function called with information about the post wire add operation result. * * @param cls closure with a `struct WireAddRequest` - * @param hr HTTP response data + * @param wer response data */ static void wire_add_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer) { struct WireAddRequest *war = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &wer->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -1533,10 +1536,21 @@ upload_wire_add (const char *exchange_url, struct GNUNET_TIME_Timestamp start_time; struct WireAddRequest *war; const char *err_name; + const char *conversion_url = NULL; + json_t *debit_restrictions; + json_t *credit_restrictions; unsigned int err_line; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("payto_uri", &payto_uri), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("conversion_url", + &conversion_url), + NULL), + GNUNET_JSON_spec_json ("debit_restrictions", + &debit_restrictions), + GNUNET_JSON_spec_json ("credit_restrictions", + &credit_restrictions), GNUNET_JSON_spec_timestamp ("validity_start", &start_time), GNUNET_JSON_spec_fixed_auto ("master_sig_add", @@ -1561,6 +1575,7 @@ upload_wire_add (const char *exchange_url, stderr, JSON_INDENT (2)); global_ret = EXIT_FAILURE; + GNUNET_JSON_parse_free (spec); test_shutdown (); return; } @@ -1574,6 +1589,7 @@ upload_wire_add (const char *exchange_url, "payto:// URI `%s' is malformed\n", payto_uri); global_ret = EXIT_FAILURE; + GNUNET_JSON_parse_free (spec); test_shutdown (); return; } @@ -1588,6 +1604,7 @@ upload_wire_add (const char *exchange_url, "payto URI is malformed: %s\n", msg); GNUNET_free (msg); + GNUNET_JSON_parse_free (spec); test_shutdown (); global_ret = EXIT_INVALIDARGUMENT; return; @@ -1599,6 +1616,9 @@ upload_wire_add (const char *exchange_url, TALER_EXCHANGE_management_enable_wire (ctx, exchange_url, payto_uri, + conversion_url, + debit_restrictions, + credit_restrictions, start_time, &master_sig_add, &master_sig_wire, @@ -1607,6 +1627,7 @@ upload_wire_add (const char *exchange_url, GNUNET_CONTAINER_DLL_insert (war_head, war_tail, war); + GNUNET_JSON_parse_free (spec); } @@ -1614,13 +1635,14 @@ upload_wire_add (const char *exchange_url, * Function called with information about the post wire del operation result. * * @param cls closure with a `struct WireDelRequest` - * @param hr HTTP response data + * @param wdres response data */ static void wire_del_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdres) { struct WireDelRequest *wdr = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &wdres->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -1927,14 +1949,15 @@ upload_global_fee (const char *exchange_url, * Function called with information about the drain profits operation. * * @param cls closure with a `struct DrainProfitsRequest` - * @param hr HTTP response data + * @param mdr response data */ static void drain_profits_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementDrainResponse *mdr) { struct DrainProfitsRequest *dpr = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &mdr->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -2033,14 +2056,15 @@ upload_drain (const char *exchange_url, * Function called with information about the post upload keys operation result. * * @param cls closure with a `struct UploadKeysRequest` - * @param hr HTTP response data + * @param mr response data */ static void keys_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementPostKeysResponse *mr) { struct UploadKeysRequest *ukr = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &mr->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -2206,14 +2230,15 @@ upload_keys (const char *exchange_url, * Function called with information about the post upload extensions operation result. * * @param cls closure with a `struct UploadExtensionsRequest` - * @param hr HTTP response data + * @param er response data */ static void extensions_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementPostExtensionsResponse *er) { struct UploadExtensionsRequest *uer = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &er->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -2447,14 +2472,15 @@ add_partner (const char *exchange_url, * Function called with information about the AML officer update operation. * * @param cls closure with a `struct AmlStaffRequest` - * @param hr HTTP response data + * @param ar response data */ static void update_aml_officer_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *ar) { struct AmlStaffRequest *asr = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &ar->hr; if (MHD_HTTP_NO_CONTENT != hr->http_status) { @@ -2961,6 +2987,10 @@ do_add_wire (char *const *args) struct TALER_MasterSignatureP master_sig_add; struct TALER_MasterSignatureP master_sig_wire; struct GNUNET_TIME_Timestamp now; + const char *conversion_url = NULL; + json_t *debit_restrictions; + json_t *credit_restrictions; + unsigned int num_args = 1; if (NULL != in) { @@ -3011,24 +3041,43 @@ do_add_wire (char *const *args) } GNUNET_free (wire_method); } + // FIXME: init new args properly! + debit_restrictions = json_array (); + GNUNET_assert (NULL != debit_restrictions); + credit_restrictions = json_array (); + GNUNET_assert (NULL != credit_restrictions); + TALER_exchange_offline_wire_add_sign (args[0], + conversion_url, + debit_restrictions, + credit_restrictions, now, &master_priv, &master_sig_add); TALER_exchange_wire_signature_make (args[0], + conversion_url, + debit_restrictions, + credit_restrictions, &master_priv, &master_sig_wire); output_operation (OP_ENABLE_WIRE, GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("payto_uri", args[0]), + GNUNET_JSON_pack_array_steal ("debit_restrictions", + debit_restrictions), + GNUNET_JSON_pack_array_steal ("credit_restrictions", + credit_restrictions), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("conversion_url", + conversion_url)), GNUNET_JSON_pack_timestamp ("validity_start", now), GNUNET_JSON_pack_data_auto ("master_sig_add", &master_sig_add), GNUNET_JSON_pack_data_auto ("master_sig_wire", &master_sig_wire))); - next (args + 1); + next (args + num_args); } @@ -3643,18 +3692,15 @@ enable_aml_staff (char *const *args) * whether there are subsequent commands). * * @param cls closure with the `char **` remaining args - * @param hr HTTP response data - * @param keys information about the various keys used - * by the exchange, NULL if /management/keys failed + * @param mgr response data */ static void download_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_FutureKeys *keys) + const struct TALER_EXCHANGE_ManagementGetKeysResponse *mgr) { char *const *args = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &mgr->hr; - (void) keys; mgkh = NULL; switch (hr->http_status) { diff --git a/src/exchange/taler-exchange-httpd_config.h b/src/exchange/taler-exchange-httpd_config.h index 7763cdeb5..95380e0a8 100644 --- a/src/exchange/taler-exchange-httpd_config.h +++ b/src/exchange/taler-exchange-httpd_config.h @@ -41,7 +41,7 @@ * * Returned via both /config and /keys endpoints. */ -#define EXCHANGE_PROTOCOL_VERSION "14:0:2" +#define EXCHANGE_PROTOCOL_VERSION "15:0:0" /** diff --git a/src/exchange/taler-exchange-httpd_management_wire_disable.c b/src/exchange/taler-exchange-httpd_management_wire_disable.c index 34825eda3..077a56b25 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_disable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_disable.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 Taler Systems SA TALER 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 @@ -114,6 +114,9 @@ del_wire (void *cls, } qs = TEH_plugin->update_wire (TEH_plugin->cls, awc->payto_uri, + NULL, + NULL, + NULL, awc->validity_end, false); if (qs < 0) diff --git a/src/exchange/taler-exchange-httpd_management_wire_enable.c b/src/exchange/taler-exchange-httpd_management_wire_enable.c index 25ee0eeac..6743b485c 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_enable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_enable.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 Taler Systems SA TALER 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 @@ -54,6 +54,21 @@ struct AddWireContext */ const char *payto_uri; + /** + * (optional) address of a conversion service for this account. + */ + const char *conversion_url; + + /** + * Restrictions imposed when crediting this account. + */ + json_t *credit_restrictions; + + /** + * Restrictions imposed when debiting this account. + */ + json_t *debit_restrictions; + /** * Timestamp for checking against replay attacks. */ @@ -114,11 +129,17 @@ add_wire (void *cls, if (0 == qs) qs = TEH_plugin->insert_wire (TEH_plugin->cls, awc->payto_uri, + awc->conversion_url, + awc->debit_restrictions, + awc->credit_restrictions, awc->validity_start, &awc->master_sig_wire); else qs = TEH_plugin->update_wire (TEH_plugin->cls, awc->payto_uri, + awc->conversion_url, + awc->debit_restrictions, + awc->credit_restrictions, awc->validity_start, true); if (qs < 0) @@ -141,7 +162,9 @@ TEH_handler_management_post_wire ( struct MHD_Connection *connection, const json_t *root) { - struct AddWireContext awc; + struct AddWireContext awc = { + .conversion_url = NULL + }; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("master_sig_wire", &awc.master_sig_wire), @@ -149,6 +172,14 @@ TEH_handler_management_post_wire ( &awc.master_sig_add), GNUNET_JSON_spec_string ("payto_uri", &awc.payto_uri), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("conversion_url", + &awc.conversion_url), + NULL), + GNUNET_JSON_spec_json ("credit_restrictions", + &awc.credit_restrictions), + GNUNET_JSON_spec_json ("debit_restrictions", + &awc.debit_restrictions), GNUNET_JSON_spec_timestamp ("validity_start", &awc.validity_start), GNUNET_JSON_spec_end () @@ -179,17 +210,22 @@ TEH_handler_management_post_wire ( MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PAYTO_URI_MALFORMED, msg); + GNUNET_JSON_parse_free (spec); GNUNET_free (msg); return ret; } } if (GNUNET_OK != TALER_exchange_offline_wire_add_verify (awc.payto_uri, + awc.conversion_url, + awc.debit_restrictions, + awc.credit_restrictions, awc.validity_start, &TEH_master_public_key, &awc.master_sig_add)) { GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error ( connection, MHD_HTTP_FORBIDDEN, @@ -199,10 +235,14 @@ TEH_handler_management_post_wire ( TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; if (GNUNET_OK != TALER_exchange_wire_signature_check (awc.payto_uri, + awc.conversion_url, + awc.debit_restrictions, + awc.credit_restrictions, &TEH_master_public_key, &awc.master_sig_wire)) { GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error ( connection, MHD_HTTP_FORBIDDEN, @@ -218,6 +258,7 @@ TEH_handler_management_post_wire ( GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "payto:// URI `%s' is malformed\n", awc.payto_uri); + GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error ( connection, MHD_HTTP_BAD_REQUEST, @@ -237,6 +278,7 @@ TEH_handler_management_post_wire ( &ret, &add_wire, &awc); + GNUNET_JSON_parse_free (spec); if (GNUNET_SYSERR == res) return ret; } diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index 34010462d..17875a720 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2022 Taler Systems SA + Copyright (C) 2015-2023 Taler Systems SA TALER 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 @@ -224,12 +224,18 @@ TEH_wire_done () * * @param cls a `json_t *` object to expand with wire account details * @param payto_uri the exchange bank account URI to add + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param debit_restrictions JSON array with debit restrictions on the account + * @param credit_restrictions JSON array with credit restrictions on the account * @param master_sig master key signature affirming that this is a bank * account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS) */ static void add_wire_account (void *cls, const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, const struct TALER_MasterSignatureP *master_sig) { json_t *a = cls; @@ -240,6 +246,13 @@ add_wire_account (void *cls, GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("payto_uri", payto_uri), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("conversion_url", + conversion_url)), + GNUNET_JSON_pack_array_incref ("debit_restrictions", + (json_t *) debit_restrictions), + GNUNET_JSON_pack_array_incref ("credit_restrictions", + (json_t *) credit_restrictions), GNUNET_JSON_pack_data_auto ("master_sig", master_sig)))) { @@ -462,6 +475,8 @@ build_wire_state (void) wsh->wire_reply = TALER_MHD_MAKE_JSON_PACK ( GNUNET_JSON_pack_array_steal ("accounts", wire_accounts_array), + GNUNET_JSON_pack_array_steal ("wads", /* #7271 */ + json_array ()), GNUNET_JSON_pack_object_steal ("fees", wire_fee_object), GNUNET_JSON_pack_data_auto ("master_public_key", diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c index 235c0153f..047042423 100644 --- a/src/exchange/taler-exchange-wirewatch.c +++ b/src/exchange/taler-exchange-wirewatch.c @@ -731,8 +731,8 @@ history_cb (void *cls, { case MHD_HTTP_OK: process_reply (wrap_size, - reply->details.success.details, - reply->details.success.details_length); + reply->details.ok.details, + reply->details.ok.details_length); return; case MHD_HTTP_NO_CONTENT: transaction_completed (); diff --git a/src/exchangedb/.gitignore b/src/exchangedb/.gitignore index fa833d81f..6e67fadb1 100644 --- a/src/exchangedb/.gitignore +++ b/src/exchangedb/.gitignore @@ -12,4 +12,5 @@ test-exchangedb-batch-reserves-in-insert-postgres test-exchangedb-by-j-postgres test-exchangedb-populate-link-data-postgres test-exchangedb-populate-ready-deposit-postgres -test-exchangedb-populate-select-refunds-by-coin-postgres \ No newline at end of file +test-exchangedb-populate-select-refunds-by-coin-postgres +exchange-0004.sql diff --git a/src/exchangedb/0004-wire_accounts.sql b/src/exchangedb/0004-wire_accounts.sql new file mode 100644 index 000000000..6114c821a --- /dev/null +++ b/src/exchangedb/0004-wire_accounts.sql @@ -0,0 +1,26 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2023 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see +-- + +ALTER TABLE wire_accounts + ADD COLUMN conversion_url VARCHAR DEFAULT (NULL), + ADD COLUMN debit_restrictions VARCHAR DEFAULT (NULL), + ADD COLUMN credit_restrictions VARCHAR DEFAULT (NULL); +COMMENT ON COLUMN wire_accounts.conversion_url + IS 'URL of a currency conversion service if conversion is needed when this account is used; NULL if there is no conversion.'; +COMMENT ON COLUMN wire_accounts.debit_restrictions + IS 'JSON array describing restrictions imposed when debiting this account. Empty for no restrictions, NULL if account was migrated from previous database revision or account is disabled.'; +COMMENT ON COLUMN wire_accounts.credit_restrictions + IS 'JSON array describing restrictions imposed when crediting this account. Empty for no restrictions, NULL if account was migrated from previous database revision or account is disabled.'; diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index de76997cb..ee78b87f7 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -20,7 +20,9 @@ sqlinputs = \ 0002-*.sql \ exchange-0002.sql.in \ 0003-*.sql \ - exchange-0003.sql.in + exchange-0003.sql.in \ + 0004-*.sql \ + exchange-0004.sql.in sql_DATA = \ benchmark-0001.sql \ @@ -28,6 +30,7 @@ sql_DATA = \ exchange-0001.sql \ exchange-0002.sql \ exchange-0003.sql \ + exchange-0004.sql \ drop.sql \ procedures.sql @@ -39,7 +42,8 @@ BUILT_SOURCES = \ CLEANFILES = \ exchange-0002.sql \ - exchange-0003.sql + exchange-0003.sql \ + exchange-0004.sql procedures.sql: procedures.sql.in exchange_do_*.sql chmod +w $@ || true @@ -56,6 +60,11 @@ exchange-0003.sql: exchange-0003.sql.in 0003-*.sql gcc -E -P -undef - < exchange-0003.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ chmod ugo-w $@ +exchange-0004.sql: exchange-0004.sql.in 0004-*.sql + chmod +w $@ || true + gcc -E -P -undef - < exchange-0004.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ + chmod ugo-w $@ + EXTRA_DIST = \ exchangedb.conf \ exchangedb-postgres.conf \ diff --git a/src/exchangedb/drop.sql b/src/exchangedb/drop.sql index ecebde6f5..843cda8ec 100644 --- a/src/exchangedb/drop.sql +++ b/src/exchangedb/drop.sql @@ -21,6 +21,7 @@ BEGIN; SELECT _v.unregister_patch('exchange-0001'); SELECT _v.unregister_patch('exchange-0002'); SELECT _v.unregister_patch('exchange-0003'); +SELECT _v.unregister_patch('exchange-0004'); DROP SCHEMA exchange CASCADE; diff --git a/src/exchangedb/exchange-0004.sql.in b/src/exchangedb/exchange-0004.sql.in new file mode 100644 index 000000000..00979e193 --- /dev/null +++ b/src/exchangedb/exchange-0004.sql.in @@ -0,0 +1,24 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2014--2023 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see +-- + +BEGIN; + +SELECT _v.register_patch('exchange-0004', NULL, NULL); +SET search_path TO exchange; + +#include "0004-wire_accounts.sql" + +COMMIT; diff --git a/src/exchangedb/pg_get_wire_accounts.c b/src/exchangedb/pg_get_wire_accounts.c index 43590acf8..23b939046 100644 --- a/src/exchangedb/pg_get_wire_accounts.c +++ b/src/exchangedb/pg_get_wire_accounts.c @@ -66,10 +66,25 @@ get_wire_accounts_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { char *payto_uri; + char *conversion_url = NULL; + json_t *debit_restrictions = NULL; + json_t *credit_restrictions = NULL; struct TALER_MasterSignatureP master_sig; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_string ("payto_uri", &payto_uri), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("conversion_url", + &conversion_url), + NULL), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("debit_restrictions", + &debit_restrictions), + NULL), + GNUNET_PQ_result_spec_allow_null ( + TALER_PQ_result_spec_json ("credit_restrictions", + &credit_restrictions), + NULL), GNUNET_PQ_result_spec_auto_from_type ("master_sig", &master_sig), GNUNET_PQ_result_spec_end @@ -84,8 +99,21 @@ get_wire_accounts_cb (void *cls, ctx->status = GNUNET_SYSERR; return; } + if (NULL == debit_restrictions) + { + debit_restrictions = json_array (); + GNUNET_assert (NULL != debit_restrictions); + } + if (NULL == credit_restrictions) + { + credit_restrictions = json_array (); + GNUNET_assert (NULL != credit_restrictions); + } ctx->cb (ctx->cb_cls, payto_uri, + conversion_url, + debit_restrictions, + credit_restrictions, &master_sig); GNUNET_PQ_cleanup_result (rs); } @@ -112,6 +140,9 @@ TEH_PG_get_wire_accounts (void *cls, "get_wire_accounts", "SELECT" " payto_uri" + ",conversion_url" + ",debit_restrictions" + ",credit_restrictions" ",master_sig" " FROM wire_accounts" " WHERE is_active"); @@ -123,5 +154,4 @@ TEH_PG_get_wire_accounts (void *cls, if (GNUNET_OK != ctx.status) return GNUNET_DB_STATUS_HARD_ERROR; return qs; - } diff --git a/src/exchangedb/pg_insert_wire.c b/src/exchangedb/pg_insert_wire.c index 75323b6fc..8329a04af 100644 --- a/src/exchangedb/pg_insert_wire.c +++ b/src/exchangedb/pg_insert_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022, 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -29,12 +29,20 @@ enum GNUNET_DB_QueryStatus TEH_PG_insert_wire (void *cls, const char *payto_uri, + const char *conversion_url, + json_t *debit_restrictions, + json_t *credit_restrictions, struct GNUNET_TIME_Timestamp start_date, const struct TALER_MasterSignatureP *master_sig) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (payto_uri), + NULL == conversion_url + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (conversion_url), + TALER_PQ_query_param_json (debit_restrictions), + TALER_PQ_query_param_json (credit_restrictions), GNUNET_PQ_query_param_auto_from_type (master_sig), GNUNET_PQ_query_param_timestamp (&start_date), GNUNET_PQ_query_param_end @@ -44,11 +52,14 @@ TEH_PG_insert_wire (void *cls, "insert_wire", "INSERT INTO wire_accounts " "(payto_uri" + ",conversion_url" + ",debit_restrictions" + ",credit_restrictions" ",master_sig" ",is_active" ",last_change" ") VALUES " - "($1, $2, true, $3);"); + "($1, $2, $3, $4, $5, true, $6);"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "insert_wire", params); diff --git a/src/exchangedb/pg_insert_wire.h b/src/exchangedb/pg_insert_wire.h index 670928d7c..c949327d7 100644 --- a/src/exchangedb/pg_insert_wire.h +++ b/src/exchangedb/pg_insert_wire.h @@ -29,6 +29,9 @@ * * @param cls closure * @param payto_uri wire account of the exchange + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param debit_restrictions JSON array with debit restrictions on the account + * @param credit_restrictions JSON array with credit restrictions on the account * @param start_date date when the account was added by the offline system * (only to be used for replay detection) * @param master_sig public signature affirming the existence of the account, @@ -38,6 +41,9 @@ enum GNUNET_DB_QueryStatus TEH_PG_insert_wire (void *cls, const char *payto_uri, + const char *conversion_url, + json_t *debit_restrictions, + json_t *credit_restrictions, struct GNUNET_TIME_Timestamp start_date, const struct TALER_MasterSignatureP *master_sig); diff --git a/src/exchangedb/pg_update_wire.c b/src/exchangedb/pg_update_wire.c index 4059348c9..0c4ec7b58 100644 --- a/src/exchangedb/pg_update_wire.c +++ b/src/exchangedb/pg_update_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022, 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -29,6 +29,9 @@ enum GNUNET_DB_QueryStatus TEH_PG_update_wire (void *cls, const char *payto_uri, + const char *conversion_url, + json_t *debit_restrictions, + json_t *credit_restrictions, struct GNUNET_TIME_Timestamp change_date, bool enabled) { @@ -36,17 +39,28 @@ TEH_PG_update_wire (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (payto_uri), GNUNET_PQ_query_param_bool (enabled), + NULL == conversion_url + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (conversion_url), + enabled + ? TALER_PQ_query_param_json (debit_restrictions) + : GNUNET_PQ_query_param_null (), + enabled + ? TALER_PQ_query_param_json (credit_restrictions) + : GNUNET_PQ_query_param_null (), GNUNET_PQ_query_param_timestamp (&change_date), GNUNET_PQ_query_param_end }; - /* used in #postgres_update_wire() */ PREPARE (pg, "update_wire", "UPDATE wire_accounts" " SET" " is_active=$2" - " ,last_change=$3" + " ,conversion_url=$3" + " ,debit_restrictions=$4" + " ,credit_restrictions=$5" + " ,last_change=$6" " WHERE payto_uri=$1"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "update_wire", diff --git a/src/exchangedb/pg_update_wire.h b/src/exchangedb/pg_update_wire.h index 67038b580..360b8845a 100644 --- a/src/exchangedb/pg_update_wire.h +++ b/src/exchangedb/pg_update_wire.h @@ -24,11 +24,16 @@ #include "taler_util.h" #include "taler_json_lib.h" #include "taler_exchangedb_plugin.h" + + /** * Update information about a wire account of the exchange. * * @param cls closure * @param payto_uri account the update is about + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled + * @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled * @param change_date date when the account status was last changed * (only to be used for replay detection) * @param enabled true to enable, false to disable (the actual change) @@ -37,6 +42,9 @@ enum GNUNET_DB_QueryStatus TEH_PG_update_wire (void *cls, const char *payto_uri, + const char *conversion_url, + json_t *debit_restrictions, + json_t *credit_restrictions, struct GNUNET_TIME_Timestamp change_date, bool enabled); diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h index b5d4dcceb..5ce5e254d 100644 --- a/src/include/taler_bank_service.h +++ b/src/include/taler_bank_service.h @@ -111,6 +111,7 @@ struct TALER_BANK_AdminAddIncomingHandle; * @param timestamp time when the transaction was made. * @param json detailed response from the HTTPD, or NULL if reply was not in JSON */ +// FIXME: bad API typedef void (*TALER_BANK_AdminAddIncomingCallback) ( void *cls, @@ -199,6 +200,7 @@ struct TALER_BANK_TransferHandle; * @param row_id unique ID of the wire transfer in the bank's records * @param timestamp when did the transaction go into effect */ +// FIXME: bad API typedef void (*TALER_BANK_TransferCallback)( void *cls, @@ -337,7 +339,7 @@ struct TALER_BANK_CreditHistoryResponse */ unsigned int details_length; - } success; + } ok; } details; @@ -493,7 +495,7 @@ struct TALER_BANK_DebitHistoryResponse */ unsigned int details_length; - } success; + } ok; } details; diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 61d92483f..166440764 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -5512,6 +5512,9 @@ TALER_exchange_offline_global_fee_verify ( * Create wire account addition signature. * * @param payto_uri bank account + * @param conversion_url URL of the conversion service, or NULL if none + * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec + * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec * @param now timestamp to use for the signature (rounded) * @param master_priv private key to sign with * @param[out] master_sig where to write the signature @@ -5519,6 +5522,9 @@ TALER_exchange_offline_global_fee_verify ( void TALER_exchange_offline_wire_add_sign ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp now, const struct TALER_MasterPrivateKeyP *master_priv, struct TALER_MasterSignatureP *master_sig); @@ -5528,6 +5534,9 @@ TALER_exchange_offline_wire_add_sign ( * Verify wire account addition signature. * * @param payto_uri bank account + * @param conversion_url URL of the conversion service, or NULL if none + * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec + * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec * @param sign_time timestamp when signature was created * @param master_pub public key to verify against * @param master_sig the signature the signature @@ -5536,6 +5545,9 @@ TALER_exchange_offline_wire_add_sign ( enum GNUNET_GenericReturnValue TALER_exchange_offline_wire_add_verify ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp sign_time, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterSignatureP *master_sig); @@ -5578,6 +5590,9 @@ TALER_exchange_offline_wire_del_verify ( * Check the signature in @a master_sig. * * @param payto_uri URI that is signed + * @param conversion_url URL of the conversion service, or NULL if none + * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec + * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec * @param master_pub master public key of the exchange * @param master_sig signature of the exchange * @return #GNUNET_OK if signature is valid @@ -5585,6 +5600,9 @@ TALER_exchange_offline_wire_del_verify ( enum GNUNET_GenericReturnValue TALER_exchange_wire_signature_check ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterSignatureP *master_sig); @@ -5593,12 +5611,18 @@ TALER_exchange_wire_signature_check ( * Create a signed wire statement for the given account. * * @param payto_uri account specification + * @param conversion_url URL of the conversion service, or NULL if none + * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec + * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec * @param master_priv private key to sign with * @param[out] master_sig where to write the signature */ void TALER_exchange_wire_signature_make ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, const struct TALER_MasterPrivateKeyP *master_priv, struct TALER_MasterSignatureP *master_sig); diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 4099d6bb0..f9330ec5c 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -461,22 +461,53 @@ struct TALER_EXCHANGE_HttpResponse }; +/** + * Response from /keys. + */ +struct TALER_EXCHANGE_KeysResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on the HTTP status code. + */ + union + { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + /** + * Information about the various keys used by the exchange. + */ + const struct TALER_EXCHANGE_Keys *keys; + + /** + * Protocol compatibility information + */ + enum TALER_EXCHANGE_VersionCompatibility compat; + } ok; + } details; + +}; + + /** * Function called with information about who is auditing * a particular exchange and what keys the exchange is using. * * @param cls closure - * @param hr HTTP response data - * @param keys information about the various keys used - * by the exchange, NULL if /keys failed - * @param compat protocol compatibility information + * @param kr response from /keys */ typedef void (*TALER_EXCHANGE_CertificationCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_Keys *keys, - enum TALER_EXCHANGE_VersionCompatibility compat); + const struct TALER_EXCHANGE_KeysResponse *kr); /** @@ -712,7 +743,7 @@ TALER_EXCHANGE_get_signing_key_info ( /** - * Sorted list of fees to be paid for aggregate wire transfers. + * List sorted by @a start_date with fees to be paid for aggregate wire transfers. */ struct TALER_EXCHANGE_WireAggregateFees { @@ -743,6 +774,95 @@ struct TALER_EXCHANGE_WireAggregateFees }; +/** + * Information about wire fees by wire method. + */ +struct TALER_EXCHANGE_WireFeesByMethod +{ + /** + * Wire method with the given @e fees. + */ + const char *method; + + /** + * Linked list of wire fees the exchange charges for + * accounts of the wire @e method. + */ + struct TALER_EXCHANGE_WireAggregateFees *fees_head; + +}; + + +/** + * Type of an account restriction. + */ +enum TALER_EXCHANGE_AccountRestrictionType +{ + /** + * Invalid restriction. + */ + TALER_EXCHANGE_AR_INVALID = 0, + + /** + * Account must not be used for this operation. + */ + TALER_EXCHANGE_AR_DENY = 1, + + /** + * Other account must match given regular expression. + */ + TALER_EXCHANGE_AR_REGEX = 2 +}; + +/** + * Restrictions that apply to using a given exchange bank account. + */ +struct TALER_EXCHANGE_AccountRestriction +{ + + /** + * Type of the account restriction. + */ + enum TALER_EXCHANGE_AccountRestrictionType type; + + /** + * Restriction details depending on @e type. + */ + union + { + /** + * Details if type is #TALER_EXCHANGE_AR_REGEX. + */ + struct + { + /** + * Regular expression that the payto://-URI of the partner account must + * follow. The regular expression should follow posix-egrep, but + * without support for character classes, GNU extensions, + * back-references or intervals. See + * https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html + * for a description of the posix-egrep syntax. Applications may support + * regexes with additional features, but exchanges must not use such + * regexes. + */ + const char *posix_egrep; + + /** + * Hint for a human to understand the restriction. + */ + const char *human_hint; + + /** + * Internationalizations for the @e human_hint. Map from IETF BCP 47 + * language tax to localized human hints. + */ + const json_t *human_hint_i18n; + } regex; + } details; + +}; + + /** * Information about a wire account of the exchange. */ @@ -753,38 +873,104 @@ struct TALER_EXCHANGE_WireAccount */ const char *payto_uri; + /** + * URL of a conversion service in case using this account is subject to + * currency conversion. NULL for no conversion needed. + */ + const char *conversion_url; + + /** + * Array of restrictions that apply when crediting + * this account. + */ + struct TALER_EXCHANGE_AccountRestriction *credit_restrictions; + + /** + * Array of restrictions that apply when debiting + * this account. + */ + struct TALER_EXCHANGE_AccountRestriction *debit_restrictions; + + /** + * Length of the @e credit_restrictions array. + */ + unsigned int credit_restrictions_length; + + /** + * Length of the @e debit_restrictions array. + */ + unsigned int debit_restrictions_length; + /** * Signature of the exchange over the account (was checked by the API). */ struct TALER_MasterSignatureP master_sig; - /** - * Linked list of wire fees the exchange charges for - * accounts of the wire method matching @e payto_uri. - */ - const struct TALER_EXCHANGE_WireAggregateFees *fees; - }; /** - * Callbacks of this type are used to serve the result of submitting a - * wire format inquiry request to a exchange. + * Response to a /wire request. + */ +struct TALER_EXCHANGE_WireResponse +{ + /** + * HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on status. + */ + union + { + + /** + * Details for #MHD_HTTP_OK. + */ + struct + { + + /** + * Array of accounts of the exchange. + */ + const struct TALER_EXCHANGE_WireAccount *accounts; + + /** + * Array of wire fees by wire method. + */ + const struct TALER_EXCHANGE_WireFeesByMethod *fees; + + /** + * Length of @e accounts array. + */ + unsigned int accounts_len; + + /** + * Length of @e fees array. + */ + unsigned int fees_len; + + } ok; + + } details; +}; + + +/** + * Callbacks of this type are used to serve the result of submitting a wire + * format inquiry request to a exchange. * * If the request fails to generate a valid response from the - * exchange, @a http_status will also be zero. + * exchange, the http_status will also be zero. * * @param cls closure - * @param hr HTTP response data - * @param accounts_len length of the @a accounts array - * @param accounts list of wire accounts of the exchange, NULL on error + * @param wr response data */ typedef void (*TALER_EXCHANGE_WireCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - unsigned int accounts_len, - const struct TALER_EXCHANGE_WireAccount *accounts); + const struct TALER_EXCHANGE_WireResponse *wr); /** @@ -976,7 +1162,7 @@ struct TALER_EXCHANGE_DepositResult */ const char *transaction_base_url; - } success; + } ok; /** * Information returned if the HTTP status is @@ -1110,7 +1296,7 @@ struct TALER_EXCHANGE_BatchDepositResult */ unsigned int num_signatures; - } success; + } ok; /** * Information returned if the HTTP status is @@ -1202,23 +1388,51 @@ TALER_EXCHANGE_batch_deposit_cancel ( */ struct TALER_EXCHANGE_RefundHandle; +/** + * Response from the /refund API. + */ +struct TALER_EXCHANGE_RefundResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status code. + */ + union + { + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + /** + * Exchange key used to sign. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * The actual signature + */ + struct TALER_ExchangeSignatureP exchange_sig; + } ok; + } details; +}; + /** * Callbacks of this type are used to serve the result of submitting a * refund request to an exchange. * * @param cls closure - * @param hr HTTP response data - * @param sign_key exchange key used to sign @a obj, or NULL - * @param signature the actual signature, or NULL on error + * @param rr refund response */ typedef void (*TALER_EXCHANGE_RefundCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, - const struct TALER_ExchangeSignatureP *signature); - + const struct TALER_EXCHANGE_RefundResponse *rr); /** * Submit a refund request to the exchange and get the exchange's response. @@ -1311,7 +1525,7 @@ struct TALER_EXCHANGE_CsRMeltResponse * respective coin's withdraw operation. */ const struct TALER_ExchangeWithdrawValues *alg_values; - } success; + } ok; /** * Details if the status is #MHD_HTTP_GONE. @@ -1423,7 +1637,7 @@ struct TALER_EXCHANGE_CsRWithdrawResponse * respective coin's withdraw operation. */ struct TALER_ExchangeWithdrawValues alg_values; - } success; + } ok; /** * Details if the status is #MHD_HTTP_GONE. @@ -2209,7 +2423,7 @@ struct TALER_EXCHANGE_WithdrawResponse /** * Details if the status is #MHD_HTTP_OK. */ - struct TALER_EXCHANGE_PrivateCoinDetails success; + struct TALER_EXCHANGE_PrivateCoinDetails ok; /** * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. @@ -2336,7 +2550,7 @@ struct TALER_EXCHANGE_BatchWithdrawResponse * Length of the @e coins array. */ unsigned int num_coins; - } success; + } ok; /** * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. @@ -2430,19 +2644,46 @@ TALER_EXCHANGE_batch_withdraw_cancel ( struct TALER_EXCHANGE_BatchWithdrawHandle *wh); +/** + * Response from a withdraw2 request. + */ +struct TALER_EXCHANGE_Withdraw2Response +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * blind signature over the coin + */ + struct TALER_BlindedDenominationSignature blind_sig; + } ok; + } details; + +}; + /** * Callbacks of this type are used to serve the result of submitting a * withdraw request to a exchange without the (un)blinding factor. * * @param cls closure - * @param hr HTTP response data - * @param blind_sig blind signature over the coin, NULL on error + * @param w2r response data */ typedef void (*TALER_EXCHANGE_Withdraw2Callback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_BlindedDenominationSignature *blind_sig); + const struct TALER_EXCHANGE_Withdraw2Response *w2r); /** @@ -2492,21 +2733,53 @@ void TALER_EXCHANGE_withdraw2_cancel (struct TALER_EXCHANGE_Withdraw2Handle *wh); +/** + * Response from a batch-withdraw request (2nd variant). + */ +struct TALER_EXCHANGE_BatchWithdraw2Response +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * array of blind signatures over the coins. + */ + const struct TALER_BlindedDenominationSignature *blind_sigs; + + /** + * length of @e blind_sigs + */ + unsigned int blind_sigs_length; + + } ok; + } details; + +}; + + /** * Callbacks of this type are used to serve the result of submitting a batch * withdraw request to a exchange without the (un)blinding factor. * * @param cls closure - * @param hr HTTP response data - * @param blind_sigs array of blind signatures over the coins, NULL on error - * @param blind_sigs_length length of @a blind_sigs + * @param bw2r response data */ typedef void (*TALER_EXCHANGE_BatchWithdraw2Callback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_BlindedDenominationSignature *blind_sigs, - unsigned int blind_sigs_length); + const struct TALER_EXCHANGE_BatchWithdraw2Response *bw2r); /** @@ -2675,7 +2948,7 @@ struct TALER_EXCHANGE_MeltResponse * Gamma value chosen by the exchange. */ uint32_t noreveal_index; - } success; + } ok; } details; }; @@ -2801,7 +3074,7 @@ struct TALER_EXCHANGE_RevealResult * Number of coins returned. */ unsigned int num_coins; - } success; + } ok; } details; @@ -2947,7 +3220,7 @@ struct TALER_EXCHANGE_LinkResult * Number of coins returned. */ unsigned int num_coins; - } success; + } ok; } details; @@ -3059,19 +3332,44 @@ struct TALER_EXCHANGE_TransferData }; +/** + * Response for a GET /transfers request. + */ +struct TALER_EXCHANGE_TransfersGetResponse +{ + /** + * HTTP response. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on HTTP status code. + */ + union + { + /** + * Details if status code is #MHD_HTTP_OK. + */ + struct + { + struct TALER_EXCHANGE_TransferData td; + } ok; + + } details; +}; + + /** * Function called with detailed wire transfer data, including all * of the coin transactions that were combined into the wire transfer. * * @param cls closure - * @param hr HTTP response data - * @param ta transfer data, (set only if @a http_status is #MHD_HTTP_OK, otherwise NULL) + * @param tgr response data */ typedef void (*TALER_EXCHANGE_TransfersGetCallback)( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_TransferData *ta); + const struct TALER_EXCHANGE_TransfersGetResponse *tgr); /** @@ -3163,7 +3461,7 @@ struct TALER_EXCHANGE_GetDepositResponse */ struct TALER_Amount coin_contribution; - } success; + } ok; /** * Response if the status was #MHD_HTTP_ACCEPTED @@ -3315,6 +3613,37 @@ TALER_EXCHANGE_free_reserve_history ( struct TALER_EXCHANGE_RecoupHandle; +/** + * Response from a recoup request. + */ +struct TALER_EXCHANGE_RecoupResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * public key of the reserve receiving the recoup + */ + struct TALER_ReservePublicKeyP reserve_pub; + + } ok; + } details; + +}; + + /** * Callbacks of this type are used to return the final result of * submitting a recoup request to a exchange. If the operation was @@ -3322,14 +3651,12 @@ struct TALER_EXCHANGE_RecoupHandle; * reserve that was credited. * * @param cls closure - * @param hr HTTP response data - * @param reserve_pub public key of the reserve receiving the recoup + * @param rr response data */ typedef void (*TALER_EXCHANGE_RecoupResultCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ReservePublicKeyP *reserve_pub); + const struct TALER_EXCHANGE_RecoupResponse *rr); /** @@ -3377,19 +3704,48 @@ TALER_EXCHANGE_recoup_cancel (struct TALER_EXCHANGE_RecoupHandle *ph); struct TALER_EXCHANGE_RecoupRefreshHandle; +/** + * Response from a /recoup-refresh request. + */ +struct TALER_EXCHANGE_RecoupRefreshResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * public key of the dirty coin that was credited + */ + struct TALER_CoinSpendPublicKeyP old_coin_pub; + + } ok; + } details; + +}; + + /** * Callbacks of this type are used to return the final result of * submitting a recoup-refresh request to a exchange. * * @param cls closure - * @param hr HTTP response data - * @param old_coin_pub public key of the dirty coin that was credited + * @param rrr response data */ typedef void (*TALER_EXCHANGE_RecoupRefreshResultCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_CoinSpendPublicKeyP *old_coin_pub); + const struct TALER_EXCHANGE_RecoupRefreshResponse *rrr); /** @@ -3495,7 +3851,7 @@ struct TALER_EXCHANGE_KycStatus */ enum TALER_AmlDecisionState aml_status; - } success; + } ok; /** * KYC is required. @@ -3898,19 +4254,48 @@ struct TALER_EXCHANGE_FutureKeys }; +/** + * Response from a /management/keys request. + */ +struct TALER_EXCHANGE_ManagementGetKeysResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * information about the various keys used + * by the exchange + */ + struct TALER_EXCHANGE_FutureKeys keys; + + } ok; + } details; + +}; + + /** * Function called with information about future keys. * * @param cls closure - * @param hr HTTP response data - * @param keys information about the various keys used - * by the exchange, NULL if /management/keys failed + * @param mgr HTTP response data */ typedef void (*TALER_EXCHANGE_ManagementGetKeysCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_FutureKeys *keys); + const struct TALER_EXCHANGE_ManagementGetKeysResponse *mgr); /** @@ -4012,16 +4397,29 @@ struct TALER_EXCHANGE_ManagementPostKeysData }; +/** + * Response from a POST /management/keys request. + */ +struct TALER_EXCHANGE_ManagementPostKeysResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + /** * Function called with information about the post keys operation result. * * @param cls closure - * @param hr HTTP response data + * @param mr response data */ typedef void (*TALER_EXCHANGE_ManagementPostKeysCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementPostKeysResponse *mr); /** @@ -4071,6 +4469,20 @@ struct TALER_EXCHANGE_ManagementPostExtensionsData struct TALER_MasterSignatureP extensions_sig; }; + +/** + * Response from a POST /management/extensions request. + */ +struct TALER_EXCHANGE_ManagementPostExtensionsResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + /** * Function called with information about the post extensions operation result. * @@ -4080,7 +4492,7 @@ struct TALER_EXCHANGE_ManagementPostExtensionsData typedef void (*TALER_EXCHANGE_ManagementPostExtensionsCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementPostExtensionsResponse *hr); /** * @brief Handle for a POST /management/extensions request. @@ -4118,6 +4530,19 @@ TALER_EXCHANGE_management_post_extensions_cancel ( struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph); +/** + * Response from a POST /management/drain request. + */ +struct TALER_EXCHANGE_ManagementDrainResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + /** * Function called with information about the drain profits result. * @@ -4127,7 +4552,7 @@ TALER_EXCHANGE_management_post_extensions_cancel ( typedef void (*TALER_EXCHANGE_ManagementDrainProfitsCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementDrainResponse *hr); /** @@ -4175,6 +4600,19 @@ TALER_EXCHANGE_management_drain_profits_cancel ( struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp); +/** + * Response from a POST /management/denominations/$DENOM/revoke request. + */ +struct TALER_EXCHANGE_ManagementRevokeDenominationResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + /** * Function called with information about the post revocation operation result. * @@ -4184,7 +4622,7 @@ TALER_EXCHANGE_management_drain_profits_cancel ( typedef void (*TALER_EXCHANGE_ManagementRevokeDenominationKeyCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *hr); /** @@ -4224,6 +4662,18 @@ TALER_EXCHANGE_management_revoke_denomination_key_cancel ( struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh); +/** + * Response from a POST /management/signkeys/$SK/revoke request. + */ +struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + /** * Function called with information about the post revocation operation result. * @@ -4233,7 +4683,7 @@ TALER_EXCHANGE_management_revoke_denomination_key_cancel ( typedef void (*TALER_EXCHANGE_ManagementRevokeSigningKeyCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *hr); /** @@ -4273,6 +4723,18 @@ TALER_EXCHANGE_management_revoke_signing_key_cancel ( struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh); +/** + * Response from a POST /management/aml-officers request. + */ +struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + /** * Function called with information about the change to * an AML officer status. @@ -4283,7 +4745,7 @@ TALER_EXCHANGE_management_revoke_signing_key_cancel ( typedef void (*TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *hr); /** @@ -4390,7 +4852,7 @@ struct TALER_EXCHANGE_AmlDecisionsResponse */ unsigned int decisions_length; - } success; + } ok; } details; }; @@ -4547,7 +5009,7 @@ struct TALER_EXCHANGE_AmlDecisionResponse */ unsigned int kyc_attributes_length; - } success; + } ok; } details; }; @@ -4617,6 +5079,7 @@ struct TALER_EXCHANGE_AddAmlDecision; * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_AddAmlDecisionCallback) ( void *cls, @@ -4672,6 +5135,7 @@ TALER_EXCHANGE_add_aml_decision_cancel ( * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_ManagementAddPartnerCallback) ( void *cls, @@ -4732,6 +5196,7 @@ TALER_EXCHANGE_management_add_partner_cancel ( * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_ManagementAuditorEnableCallback) ( void *cls, @@ -4787,6 +5252,7 @@ TALER_EXCHANGE_management_enable_auditor_cancel ( * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_ManagementAuditorDisableCallback) ( void *cls, @@ -4832,16 +5298,28 @@ TALER_EXCHANGE_management_disable_auditor_cancel ( struct TALER_EXCHANGE_ManagementAuditorDisableHandle *ah); +/** + * Response from an exchange account/enable operation. + */ +struct TALER_EXCHANGE_ManagementWireEnableResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + + /** * Function called with information about the wire enable operation result. * * @param cls closure - * @param hr HTTP response data + * @param wer HTTP response data */ typedef void (*TALER_EXCHANGE_ManagementWireEnableCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer); /** @@ -4856,6 +5334,9 @@ struct TALER_EXCHANGE_ManagementWireEnableHandle; * @param ctx the context * @param url HTTP base URL for the exchange * @param payto_uri RFC 8905 URI of the exchange's bank account + * @param conversion_url URL of the conversion service, or NULL if none + * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec + * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec * @param validity_start when was this decided? * @param master_sig1 signature affirming the wire addition * of purpose #TALER_SIGNATURE_MASTER_ADD_WIRE @@ -4870,6 +5351,9 @@ TALER_EXCHANGE_management_enable_wire ( struct GNUNET_CURL_Context *ctx, const char *url, const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp validity_start, const struct TALER_MasterSignatureP *master_sig1, const struct TALER_MasterSignatureP *master_sig2, @@ -4887,16 +5371,27 @@ TALER_EXCHANGE_management_enable_wire_cancel ( struct TALER_EXCHANGE_ManagementWireEnableHandle *wh); +/** + * Response from an exchange account/disable operation. + */ +struct TALER_EXCHANGE_ManagementWireDisableResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + /** * Function called with information about the wire disable operation result. * * @param cls closure - * @param hr HTTP response data + * @param wdr response data */ typedef void (*TALER_EXCHANGE_ManagementWireDisableCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdr); /** @@ -4945,6 +5440,7 @@ TALER_EXCHANGE_management_disable_wire_cancel ( * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_ManagementSetWireFeeCallback) ( void *cls, @@ -5001,6 +5497,7 @@ TALER_EXCHANGE_management_set_wire_fees_cancel ( * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_ManagementSetGlobalFeeCallback) ( void *cls, @@ -5062,6 +5559,7 @@ TALER_EXCHANGE_management_set_global_fees_cancel ( * @param cls closure * @param hr HTTP response data */ +// FIXME: bad API typedef void (*TALER_EXCHANGE_AuditorAddDenominationCallback) ( void *cls, @@ -5147,7 +5645,7 @@ struct TALER_EXCHANGE_ContractGetResponse */ size_t econtract_size; - } success; + } ok; } details; @@ -5243,7 +5741,7 @@ struct TALER_EXCHANGE_PurseGetResponse */ struct GNUNET_TIME_Timestamp purse_expiration; - } success; + } ok; } details; @@ -5333,7 +5831,7 @@ struct TALER_EXCHANGE_PurseCreateDepositResponse struct TALER_ExchangeSignatureP exchange_sig; - } success; + } ok; } details; @@ -5532,7 +6030,7 @@ struct TALER_EXCHANGE_AccountMergeResponse */ struct GNUNET_TIME_Timestamp etime; - } success; + } ok; /** * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. @@ -5640,7 +6138,7 @@ struct TALER_EXCHANGE_PurseCreateMergeResponse struct { - } success; + } ok; /** * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. @@ -5760,7 +6258,7 @@ struct TALER_EXCHANGE_PurseDepositResponse */ struct TALER_PrivateContractHashP h_contract_terms; - } success; + } ok; } details; }; diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 7c1757642..d025b5327 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -2881,6 +2881,9 @@ typedef enum GNUNET_GenericReturnValue * * @param cls closure * @param payto_uri the exchange bank account URI + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param debit_restrictions JSON array with debit restrictions on the account + * @param credit_restrictions JSON array with credit restrictions on the account * @param master_sig master key signature affirming that this is a bank * account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS) */ @@ -2888,6 +2891,9 @@ typedef void (*TALER_EXCHANGEDB_WireAccountCallback)( void *cls, const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, const struct TALER_MasterSignatureP *master_sig); @@ -5544,6 +5550,9 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls closure * @param payto_uri wire account of the exchange + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param debit_restrictions JSON array with debit restrictions on the account + * @param credit_restrictions JSON array with credit restrictions on the account * @param start_date date when the account was added by the offline system * (only to be used for replay detection) * @param master_sig public signature affirming the existence of the account, @@ -5553,6 +5562,9 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*insert_wire)(void *cls, const char *payto_uri, + const char *conversion_url, + json_t *debit_restrictions, + json_t *credit_restrictions, struct GNUNET_TIME_Timestamp start_date, const struct TALER_MasterSignatureP *master_sig); @@ -5562,6 +5574,9 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls closure * @param payto_uri account the update is about + * @param conversion_url URL of a conversion service, NULL if there is no conversion + * @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled + * @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled * @param change_date date when the account status was last changed * (only to be used for replay detection) * @param enabled true to enable, false to disable (the actual change) @@ -5570,6 +5585,9 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*update_wire)(void *cls, const char *payto_uri, + const char *conversion_url, + json_t *debit_restrictions, + json_t *credit_restrictions, struct GNUNET_TIME_Timestamp change_date, bool enabled); diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 7f17df030..d0749808d 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -674,33 +674,6 @@ TALER_JSON_merchant_wire_signature_hash (const json_t *wire_s, struct TALER_MerchantWireHashP *hc); -/** - * Check the signature in @a wire_s. Also performs rudimentary - * checks on the account data *if* supported. - * - * @param wire_s signed wire information of an exchange - * @param master_pub master public key of the exchange - * @return #GNUNET_OK if signature is valid - */ -enum GNUNET_GenericReturnValue -TALER_JSON_exchange_wire_signature_check ( - const json_t *wire_s, - const struct TALER_MasterPublicKeyP *master_pub); - - -/** - * Create a signed wire statement for the given account. - * - * @param payto_uri account specification - * @param master_priv private key to sign with - * @return NULL if @a payto_uri is malformed - */ -json_t * -TALER_JSON_exchange_wire_signature_make ( - const char *payto_uri, - const struct TALER_MasterPrivateKeyP *master_priv); - - /** * Extract a string from @a object under the field @a field, but respecting * the Taler i18n rules and the language preferences expressed in @a diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 5fc930a86..664db6ccd 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -147,15 +147,11 @@ TALER_TESTING_prepare_exchange (const char *config_filename, * * @param cls closure, typically, the "run" method containing * all the commands to be run, and a closure for it. - * @param hr http response details - * @param keys the exchange's keys. - * @param compat protocol compatibility information. + * @param kr response details */ void TALER_TESTING_cert_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_Keys *keys, - enum TALER_EXCHANGE_VersionCompatibility compat); + const struct TALER_EXCHANGE_KeysResponse *kr); /** diff --git a/src/json/Makefile.am b/src/json/Makefile.am index 2f5ec3f17..6bd5b464c 100644 --- a/src/json/Makefile.am +++ b/src/json/Makefile.am @@ -28,12 +28,10 @@ libtalerjson_la_LIBADD = \ $(XLIB) TESTS = \ - test_json \ - test_json_wire + test_json check_PROGRAMS= \ - test_json \ - test_json_wire + test_json test_json_SOURCES = \ test_json.c @@ -43,13 +41,3 @@ test_json_LDADD = \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetutil \ -ljansson - - -test_json_wire_SOURCES = \ - test_json_wire.c -test_json_wire_LDADD = \ - $(top_builddir)/src/json/libtalerjson.la \ - -lgnunetjson \ - $(top_builddir)/src/util/libtalerutil.la \ - -lgnunetutil \ - -ljansson diff --git a/src/json/json_wire.c b/src/json/json_wire.c index 544b56453..9d22d28ea 100644 --- a/src/json/json_wire.c +++ b/src/json/json_wire.c @@ -70,80 +70,6 @@ TALER_JSON_merchant_wire_signature_hash (const json_t *wire_s, } -enum GNUNET_GenericReturnValue -TALER_JSON_exchange_wire_signature_check ( - const json_t *wire_s, - const struct TALER_MasterPublicKeyP *master_pub) -{ - const char *payto_uri; - struct TALER_MasterSignatureP master_sig; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("payto_uri", - &payto_uri), - GNUNET_JSON_spec_fixed_auto ("master_sig", - &master_sig), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (wire_s, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - { - char *err; - - err = TALER_payto_validate (payto_uri); - if (NULL != err) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "URI `%s' ill-formed: %s\n", - payto_uri, - err); - GNUNET_free (err); - return GNUNET_SYSERR; - } - } - - return TALER_exchange_wire_signature_check (payto_uri, - master_pub, - &master_sig); -} - - -json_t * -TALER_JSON_exchange_wire_signature_make ( - const char *payto_uri, - const struct TALER_MasterPrivateKeyP *master_priv) -{ - struct TALER_MasterSignatureP master_sig; - char *err; - - if (NULL != - (err = TALER_payto_validate (payto_uri))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Invalid payto URI `%s': %s\n", - payto_uri, - err); - GNUNET_free (err); - return NULL; - } - TALER_exchange_wire_signature_make (payto_uri, - master_priv, - &master_sig); - return GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("payto_uri", - payto_uri), - GNUNET_JSON_pack_data_auto ("master_sig", - &master_sig)); -} - - char * TALER_JSON_wire_to_payto (const json_t *wire_s) { diff --git a/src/json/test_json_wire.c b/src/json/test_json_wire.c deleted file mode 100644 index b417b25fe..000000000 --- a/src/json/test_json_wire.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - This file is part of TALER - (C) 2015, 2016 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see -*/ - -/** - * @file json/test_json_wire.c - * @brief Tests for Taler-specific crypto logic - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler_util.h" -#include "taler_json_lib.h" - - -int -main (int argc, - const char *const argv[]) -{ - struct TALER_MasterPublicKeyP master_pub; - struct TALER_MasterPrivateKeyP master_priv; - json_t *wire_xtalerbank; - json_t *wire_iban; - const char *payto_xtalerbank = "payto://x-taler-bank/42"; - const char *payto_iban = - "payto://iban/BIC-TO-BE-SKIPPED/DE89370400440532013000?receiver-name=Test"; - char *p_xtalerbank; - char *p_iban; - - (void) argc; - (void) argv; - GNUNET_log_setup ("test-json-wire", - "WARNING", - NULL); - GNUNET_CRYPTO_eddsa_key_create (&master_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv, - &master_pub.eddsa_pub); - wire_xtalerbank = TALER_JSON_exchange_wire_signature_make (payto_xtalerbank, - &master_priv); - wire_iban = TALER_JSON_exchange_wire_signature_make (payto_iban, - &master_priv); - if (NULL == wire_iban) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not parse payto/IBAN (%s) into 'wire object'\n", - payto_iban); - return 1; - } - p_xtalerbank = TALER_JSON_wire_to_payto (wire_xtalerbank); - p_iban = TALER_JSON_wire_to_payto (wire_iban); - GNUNET_assert (0 == strcmp (p_xtalerbank, payto_xtalerbank)); - GNUNET_assert (0 == strcmp (p_iban, payto_iban)); - GNUNET_free (p_xtalerbank); - GNUNET_free (p_iban); - - GNUNET_assert (GNUNET_OK == - TALER_JSON_exchange_wire_signature_check (wire_xtalerbank, - &master_pub)); - GNUNET_assert (GNUNET_OK == - TALER_JSON_exchange_wire_signature_check (wire_iban, - &master_pub)); - json_decref (wire_xtalerbank); - json_decref (wire_iban); - - return 0; -} - - -/* end of test_json_wire.c */ diff --git a/src/lib/exchange_api_batch_deposit.c b/src/lib/exchange_api_batch_deposit.c index 4665908d2..c583d5add 100644 --- a/src/lib/exchange_api_batch_deposit.c +++ b/src/lib/exchange_api_batch_deposit.c @@ -247,7 +247,7 @@ handle_deposit_finished (void *cls, &dh->exchange_pub), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("transaction_base_url", - &dr.details.success.transaction_base_url), + &dr.details.ok.transaction_base_url), NULL), GNUNET_JSON_spec_timestamp ("exchange_timestamp", &dh->exchange_timestamp), @@ -332,7 +332,7 @@ handle_deposit_finished (void *cls, GNUNET_break_op (0); dr.hr.http_status = 0; dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE; - GNUNET_JSON_parse_free (spec); + GNUNET_JSON_parse_free (spec); break; } } @@ -341,10 +341,10 @@ handle_deposit_finished (void *cls, dh); GNUNET_JSON_parse_free (spec); } - dr.details.success.exchange_sigs = dh->exchange_sigs; - dr.details.success.exchange_pub = &dh->exchange_pub; - dr.details.success.deposit_timestamp = dh->exchange_timestamp; - dr.details.success.num_signatures = dh->num_cdds; + dr.details.ok.exchange_sigs = dh->exchange_sigs; + dr.details.ok.exchange_pub = &dh->exchange_pub; + dr.details.ok.deposit_timestamp = dh->exchange_timestamp; + dr.details.ok.num_signatures = dh->num_cdds; break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy diff --git a/src/lib/exchange_api_batch_withdraw.c b/src/lib/exchange_api_batch_withdraw.c index 9bb158f87..4817ae403 100644 --- a/src/lib/exchange_api_batch_withdraw.c +++ b/src/lib/exchange_api_batch_withdraw.c @@ -144,37 +144,34 @@ struct TALER_EXCHANGE_BatchWithdrawHandle * HTTP /reserves/$RESERVE_PUB/batch-withdraw request. * * @param cls the `struct TALER_EXCHANGE_BatchWithdrawHandle` - * @param hr HTTP response data - * @param blind_sigs array of blind signatures over the coins, NULL on error - * @param blind_sigs_length length of the @a blind_sigs array + * @param bw2r response data */ static void handle_reserve_batch_withdraw_finished ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_BlindedDenominationSignature *blind_sigs, - unsigned int blind_sigs_length) + const struct TALER_EXCHANGE_BatchWithdraw2Response *bw2r) { struct TALER_EXCHANGE_BatchWithdrawHandle *wh = cls; struct TALER_EXCHANGE_BatchWithdrawResponse wr = { - .hr = *hr + .hr = bw2r->hr }; - struct TALER_EXCHANGE_PrivateCoinDetails coins[wh->num_coins]; + struct TALER_EXCHANGE_PrivateCoinDetails coins[GNUNET_NZL (wh->num_coins)]; wh->wh2 = NULL; memset (coins, 0, sizeof (coins)); - if (blind_sigs_length != wh->num_coins) - { - GNUNET_break_op (0); - wr.hr.http_status = 0; - wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - } - switch (hr->http_status) + switch (bw2r->hr.http_status) { case MHD_HTTP_OK: { + if (bw2r->details.ok.blind_sigs_length != wh->num_coins) + { + GNUNET_break_op (0); + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } for (unsigned int i = 0; inum_coins; i++) { struct CoinData *cd = &wh->coins[i]; @@ -183,7 +180,7 @@ handle_reserve_batch_withdraw_finished ( if (GNUNET_OK != TALER_planchet_to_coin (&cd->pk.key, - &blind_sigs[i], + &bw2r->details.ok.blind_sigs[i], &cd->bks, &cd->priv, cd->ach, @@ -200,8 +197,8 @@ handle_reserve_batch_withdraw_finished ( coin->sig = fc.sig; coin->exchange_vals = cd->alg_values; } - wr.details.success.coins = coins; - wr.details.success.num_coins = wh->num_coins; + wr.details.ok.coins = coins; + wr.details.ok.num_coins = wh->num_coins; break; } case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: @@ -217,7 +214,7 @@ handle_reserve_batch_withdraw_finished ( }; if (GNUNET_OK != - GNUNET_JSON_parse (hr->reply, + GNUNET_JSON_parse (bw2r->hr.reply, spec, NULL, NULL)) { @@ -289,7 +286,7 @@ withdraw_cs_stage_two_callback ( switch (csrr->hr.http_status) { case MHD_HTTP_OK: - cd->alg_values = csrr->details.success.alg_values; + cd->alg_values = csrr->details.ok.alg_values; TALER_planchet_setup_coin_priv (&cd->ps, &cd->alg_values, &cd->priv); diff --git a/src/lib/exchange_api_batch_withdraw2.c b/src/lib/exchange_api_batch_withdraw2.c index e14ed92fd..04c2c0100 100644 --- a/src/lib/exchange_api_batch_withdraw2.c +++ b/src/lib/exchange_api_batch_withdraw2.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -108,9 +108,9 @@ reserve_batch_withdraw_ok (struct TALER_EXCHANGE_BatchWithdraw2Handle *wh, "ev_sigs"); const json_t *j; unsigned int index; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = json, - .http_status = MHD_HTTP_OK + struct TALER_EXCHANGE_BatchWithdraw2Response bwr = { + .hr.reply = json, + .hr.http_status = MHD_HTTP_OK }; if ( (NULL == ja) || @@ -141,10 +141,10 @@ reserve_batch_withdraw_ok (struct TALER_EXCHANGE_BatchWithdraw2Handle *wh, } /* signature is valid, return it to the application */ + bwr.details.ok.blind_sigs = blind_sigs; + bwr.details.ok.blind_sigs_length = wh->num_coins; wh->cb (wh->cb_cls, - &hr, - blind_sigs, - wh->num_coins); + &bwr); /* make sure callback isn't called again after return */ wh->cb = NULL; for (unsigned int i = 0; inum_coins; i++) @@ -264,16 +264,16 @@ handle_reserve_batch_withdraw_finished (void *cls, { struct TALER_EXCHANGE_BatchWithdraw2Handle *wh = cls; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_BatchWithdraw2Response bwr = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; wh->job = NULL; switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + bwr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: if (GNUNET_OK != @@ -281,8 +281,8 @@ handle_reserve_batch_withdraw_finished (void *cls, j)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + bwr.hr.http_status = 0; + bwr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } GNUNET_assert (NULL == wh->cb); @@ -304,8 +304,8 @@ handle_reserve_batch_withdraw_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + bwr.hr.http_status = 0; + bwr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } } @@ -313,24 +313,24 @@ handle_reserve_batch_withdraw_finished (void *cls, case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_FORBIDDEN: GNUNET_break_op (0); /* Nothing really to verify, exchange says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, the exchange basically just says that it doesn't know this reserve. Can happen if we query before the wire transfer went through. We should simply pass the JSON reply to the application. */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_CONFLICT: /* The exchange says that the reserve has insufficient funds; @@ -340,13 +340,13 @@ handle_reserve_batch_withdraw_finished (void *cls, j)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + bwr.hr.http_status = 0; + bwr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; } else { - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); } break; case MHD_HTTP_GONE: @@ -354,32 +354,30 @@ handle_reserve_batch_withdraw_finished (void *cls, /* Note: one might want to check /keys for revocation signature here, alas tricky in case our /keys is outdated => left to clients */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + bwr.hr.ec = TALER_JSON_get_error_code (j); + bwr.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange batch withdraw\n", (unsigned int) response_code, - (int) hr.ec); + (int) bwr.hr.ec); break; } if (NULL != wh->cb) { wh->cb (wh->cb_cls, - &hr, - NULL, - 0); + &bwr); wh->cb = NULL; } TALER_EXCHANGE_batch_withdraw2_cancel (wh); diff --git a/src/lib/exchange_api_contracts_get.c b/src/lib/exchange_api_contracts_get.c index 263a0cbe9..8fd4ba1e7 100644 --- a/src/lib/exchange_api_contracts_get.c +++ b/src/lib/exchange_api_contracts_get.c @@ -109,7 +109,7 @@ handle_contract_get_finished (void *cls, struct TALER_PurseContractSignatureP econtract_sig; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("purse_pub", - &dr.details.success.purse_pub), + &dr.details.ok.purse_pub), GNUNET_JSON_spec_fixed_auto ("econtract_sig", &econtract_sig), GNUNET_JSON_spec_varsize ("econtract", @@ -133,7 +133,7 @@ handle_contract_get_finished (void *cls, econtract, econtract_size, &cgh->cpub, - &dr.details.success.purse_pub, + &dr.details.ok.purse_pub, &econtract_sig)) { GNUNET_break (0); @@ -142,8 +142,8 @@ handle_contract_get_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } - dr.details.success.econtract = econtract; - dr.details.success.econtract_size = econtract_size; + dr.details.ok.econtract = econtract; + dr.details.ok.econtract_size = econtract_size; cgh->cb (cgh->cb_cls, &dr); GNUNET_JSON_parse_free (spec); diff --git a/src/lib/exchange_api_csr_melt.c b/src/lib/exchange_api_csr_melt.c index 9de8cd8d9..67b1a9b7e 100644 --- a/src/lib/exchange_api_csr_melt.c +++ b/src/lib/exchange_api_csr_melt.c @@ -94,8 +94,8 @@ csr_ok (struct TALER_EXCHANGE_CsRMeltHandle *csrh, struct TALER_ExchangeWithdrawValues alg_values[GNUNET_NZL (alen)]; struct TALER_EXCHANGE_CsRMeltResponse csrr = { .hr = *hr, - .details.success.alg_values_len = alen, - .details.success.alg_values = alg_values + .details.ok.alg_values_len = alen, + .details.ok.alg_values = alg_values }; for (unsigned int i = 0; iexchange_pub), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("transaction_base_url", - &dr.details.success.transaction_base_url), + &dr.details.ok.transaction_base_url), NULL), GNUNET_JSON_spec_timestamp ("exchange_timestamp", &dh->exchange_timestamp), @@ -297,9 +297,9 @@ handle_deposit_finished (void *cls, &auditor_cb, dh); } - dr.details.success.exchange_sig = &dh->exchange_sig; - dr.details.success.exchange_pub = &dh->exchange_pub; - dr.details.success.deposit_timestamp = dh->exchange_timestamp; + dr.details.ok.exchange_sig = &dh->exchange_sig; + dr.details.ok.exchange_pub = &dh->exchange_pub; + dr.details.ok.deposit_timestamp = dh->exchange_timestamp; break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index 2e8a5e5e8..bd5f2f653 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -118,15 +118,15 @@ handle_deposit_wtid_finished (void *cls, { struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("wtid", - &dr.details.success.wtid), + &dr.details.ok.wtid), GNUNET_JSON_spec_timestamp ("execution_time", - &dr.details.success.execution_time), + &dr.details.ok.execution_time), TALER_JSON_spec_amount_any ("coin_contribution", - &dr.details.success.coin_contribution), + &dr.details.ok.coin_contribution), GNUNET_JSON_spec_fixed_auto ("exchange_sig", - &dr.details.success.exchange_sig), + &dr.details.ok.exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", - &dr.details.success.exchange_pub), + &dr.details.ok.exchange_pub), GNUNET_JSON_spec_end () }; const struct TALER_EXCHANGE_Keys *key_state; @@ -145,7 +145,7 @@ handle_deposit_wtid_finished (void *cls, } if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &dr.details.success.exchange_pub)) + &dr.details.ok.exchange_pub)) { GNUNET_break_op (0); dr.hr.http_status = 0; @@ -156,12 +156,12 @@ handle_deposit_wtid_finished (void *cls, TALER_exchange_online_confirm_wire_verify ( &dwh->h_wire, &dwh->h_contract_terms, - &dr.details.success.wtid, + &dr.details.ok.wtid, &dwh->coin_pub, - dr.details.success.execution_time, - &dr.details.success.coin_contribution, - &dr.details.success.exchange_pub, - &dr.details.success.exchange_sig)) + dr.details.ok.execution_time, + &dr.details.ok.coin_contribution, + &dr.details.ok.exchange_pub, + &dr.details.ok.exchange_sig)) { GNUNET_break_op (0); dr.hr.http_status = 0; diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 8501ed11d..f6a5e979d 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -40,7 +40,7 @@ * Which version of the Taler protocol is implemented * by this library? Used to determine compatibility. */ -#define EXCHANGE_PROTOCOL_CURRENT 14 +#define EXCHANGE_PROTOCOL_CURRENT 15 /** * How many versions are we backwards compatible with? @@ -1305,15 +1305,18 @@ keys_completed_cb (void *cls, { struct KeysRequest *kr = cls; struct TALER_EXCHANGE_Handle *exchange = kr->exchange; - struct TALER_EXCHANGE_Keys kd; struct TALER_EXCHANGE_Keys kd_old; - enum TALER_EXCHANGE_VersionCompatibility vc; const json_t *j = resp_obj; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_Keys kd; + struct TALER_EXCHANGE_KeysResponse kresp = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code, + .details.ok.compat = TALER_EXCHANGE_VC_PROTOCOL_ERROR, }; + memset (&kd, + 0, + sizeof (kd)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received keys from URL `%s' with status %ld and expiration %s.\n", kr->url, @@ -1330,10 +1333,6 @@ keys_completed_cb (void *cls, GNUNET_TIME_relative_to_absolute (DEFAULT_EXPIRATION)); } kd_old = exchange->key_data; - memset (&kd, - 0, - sizeof (struct TALER_EXCHANGE_Keys)); - vc = TALER_EXCHANGE_VC_PROTOCOL_ERROR; switch (response_code) { case 0: @@ -1358,8 +1357,10 @@ keys_completed_cb (void *cls, } /* We keep the denomination keys and auditor signatures from the previous iteration (/keys cherry picking) */ - kd.num_denom_keys = kd_old.num_denom_keys; - kd.last_denom_issue_date = kd_old.last_denom_issue_date; + kd.num_denom_keys + = kd_old.num_denom_keys; + kd.last_denom_issue_date + = kd_old.last_denom_issue_date; GNUNET_array_grow (kd.denom_keys, kd.denom_keys_size, kd.num_denom_keys); @@ -1401,11 +1402,11 @@ keys_completed_cb (void *cls, decode_keys_json (j, true, &kd, - &vc)) + &kresp.details.ok.compat)) { TALER_LOG_ERROR ("Could not decode /keys response\n"); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + kresp.hr.http_status = 0; + kresp.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; for (unsigned int i = 0; ikeys_error_count++; if (NULL == j) { - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = TALER_ErrorCode_get_hint (hr.ec); + kresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + kresp.hr.hint = TALER_ErrorCode_get_hint (kresp.hr.ec); } else { - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + kresp.hr.ec = TALER_JSON_get_error_code (j); + kresp.hr.hint = TALER_JSON_get_error_hint (j); } GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) kresp.hr.ec); break; } exchange->key_data = kd; @@ -1491,9 +1492,7 @@ keys_completed_cb (void *cls, free_key_data (&kd_old); /* notify application that we failed */ exchange->cert_cb (exchange->cert_cb_cls, - &hr, - NULL, - vc); + &kresp); return; } @@ -1504,11 +1503,11 @@ keys_completed_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Successfully downloaded exchange's keys\n"); update_auditors (exchange); + kresp.details.ok.keys = &exchange->key_data; + /* notify application about the key information */ exchange->cert_cb (exchange->cert_cb_cls, - &hr, - &exchange->key_data, - vc); + &kresp); free_key_data (&kd_old); } @@ -1702,7 +1701,6 @@ static void deserialize_data (struct TALER_EXCHANGE_Handle *exchange, const json_t *data) { - enum TALER_EXCHANGE_VersionCompatibility vc; json_t *keys; const char *url; uint32_t version; @@ -1719,10 +1717,11 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange, GNUNET_JSON_spec_end () }; struct TALER_EXCHANGE_Keys key_data; - struct TALER_EXCHANGE_HttpResponse hr = { - .ec = TALER_EC_NONE, - .http_status = MHD_HTTP_OK, - .reply = data + struct TALER_EXCHANGE_KeysResponse kresp = { + .hr.ec = TALER_EC_NONE, + .hr.http_status = MHD_HTTP_OK, + .hr.reply = data, + .details.ok.keys = &exchange->key_data }; if (NULL == data) @@ -1754,7 +1753,7 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange, decode_keys_json (keys, false, &key_data, - &vc)) + &kresp.details.ok.compat)) { GNUNET_break (0); GNUNET_JSON_parse_free (spec); @@ -1771,9 +1770,7 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange, update_auditors (exchange); /* notify application about the key information */ exchange->cert_cb (exchange->cert_cb_cls, - &hr, - &exchange->key_data, - vc); + &kresp); GNUNET_JSON_parse_free (spec); } @@ -2056,17 +2053,18 @@ request_keys (void *cls) url); if (NULL == kr->url) { - struct TALER_EXCHANGE_HttpResponse hr = { - .ec = TALER_EC_GENERIC_CONFIGURATION_INVALID + struct TALER_EXCHANGE_KeysResponse kresp = { + .hr.ec = TALER_EC_GENERIC_CONFIGURATION_INVALID, + /* Next line is technically unnecessary, as the + http status we set is 0 */ + .details.ok.compat = TALER_EXCHANGE_VC_PROTOCOL_ERROR }; GNUNET_free (kr); exchange->keys_error_count++; exchange->state = MHS_FAILED; exchange->cert_cb (exchange->cert_cb_cls, - &hr, - NULL, - TALER_EXCHANGE_VC_PROTOCOL_ERROR); + &kresp); return; } diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c index 2f03730a8..d1580e76c 100644 --- a/src/lib/exchange_api_kyc_check.c +++ b/src/lib/exchange_api_kyc_check.c @@ -100,11 +100,11 @@ handle_kyc_check_finished (void *cls, uint32_t status; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", - &ks.details.success.exchange_sig), + &ks.details.ok.exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", - &ks.details.success.exchange_pub), + &ks.details.ok.exchange_pub), GNUNET_JSON_spec_timestamp ("now", - &ks.details.success.timestamp), + &ks.details.ok.timestamp), GNUNET_JSON_spec_json ("kyc_details", &kyc_details), GNUNET_JSON_spec_uint32 ("aml_status", @@ -123,13 +123,13 @@ handle_kyc_check_finished (void *cls, ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - ks.details.success.kyc_details = kyc_details; - ks.details.success.aml_status + ks.details.ok.kyc_details = kyc_details; + ks.details.ok.aml_status = (enum TALER_AmlDecisionState) status; key_state = TALER_EXCHANGE_get_keys (kch->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &ks.details.success.exchange_pub)) + &ks.details.ok.exchange_pub)) { GNUNET_break_op (0); ks.http_status = 0; @@ -141,10 +141,10 @@ handle_kyc_check_finished (void *cls, if (GNUNET_OK != TALER_exchange_online_account_setup_success_verify ( &kch->h_payto, - ks.details.success.kyc_details, - ks.details.success.timestamp, - &ks.details.success.exchange_pub, - &ks.details.success.exchange_sig)) + ks.details.ok.kyc_details, + ks.details.ok.timestamp, + &ks.details.ok.exchange_pub, + &ks.details.ok.exchange_sig)) { GNUNET_break_op (0); ks.http_status = 0; diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c index 9e8625ed5..3b998f23a 100644 --- a/src/lib/exchange_api_link.c +++ b/src/lib/exchange_api_link.c @@ -365,8 +365,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh, if (off_coin == num_coins) { - lr.details.success.num_coins = num_coins; - lr.details.success.coins = lcis; + lr.details.ok.num_coins = num_coins; + lr.details.ok.coins = lcis; lh->link_cb (lh->link_cb_cls, &lr); lh->link_cb = NULL; diff --git a/src/lib/exchange_api_lookup_aml_decision.c b/src/lib/exchange_api_lookup_aml_decision.c index 897a21f10..fc1a8a8e4 100644 --- a/src/lib/exchange_api_lookup_aml_decision.c +++ b/src/lib/exchange_api_lookup_aml_decision.c @@ -190,17 +190,17 @@ parse_decision_ok (struct TALER_EXCHANGE_LookupAmlDecision *lh, GNUNET_break_op (0); return GNUNET_SYSERR; } - lr.details.success.aml_history_length = json_array_size (aml_history); - lr.details.success.kyc_attributes_length = json_array_size (kyc_attributes); + lr.details.ok.aml_history_length = json_array_size (aml_history); + lr.details.ok.kyc_attributes_length = json_array_size (kyc_attributes); { struct TALER_EXCHANGE_AmlDecisionDetail aml_history_ar[ - GNUNET_NZL (lr.details.success.aml_history_length)]; + GNUNET_NZL (lr.details.ok.aml_history_length)]; struct TALER_EXCHANGE_KycHistoryDetail kyc_attributes_ar[ - lr.details.success.kyc_attributes_length]; + lr.details.ok.kyc_attributes_length]; enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; - lr.details.success.aml_history = aml_history_ar; - lr.details.success.kyc_attributes = kyc_attributes_ar; + lr.details.ok.aml_history = aml_history_ar; + lr.details.ok.kyc_attributes = kyc_attributes_ar; ret = parse_aml_history (aml_history, aml_history_ar); if (GNUNET_OK == ret) diff --git a/src/lib/exchange_api_lookup_aml_decisions.c b/src/lib/exchange_api_lookup_aml_decisions.c index f8a1d7fa3..403acb54a 100644 --- a/src/lib/exchange_api_lookup_aml_decisions.c +++ b/src/lib/exchange_api_lookup_aml_decisions.c @@ -139,13 +139,13 @@ parse_decisions_ok (struct TALER_EXCHANGE_LookupAmlDecisions *lh, GNUNET_break_op (0); return GNUNET_SYSERR; } - lr.details.success.decisions_length = json_array_size (records); + lr.details.ok.decisions_length = json_array_size (records); { struct TALER_EXCHANGE_AmlDecisionSummary decisions[ - GNUNET_NZL (lr.details.success.decisions_length)]; + GNUNET_NZL (lr.details.ok.decisions_length)]; enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; - lr.details.success.decisions = decisions; + lr.details.ok.decisions = decisions; ret = parse_aml_decisions (records, decisions); if (GNUNET_OK == ret) diff --git a/src/lib/exchange_api_management_drain_profits.c b/src/lib/exchange_api_management_drain_profits.c index 9cf1af85e..bc7232b87 100644 --- a/src/lib/exchange_api_management_drain_profits.c +++ b/src/lib/exchange_api_management_drain_profits.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2022 Taler Systems SA + Copyright (C) 2020-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -79,9 +79,9 @@ handle_drain_profits_finished (void *cls, { struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementDrainResponse dr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; dp->job = NULL; @@ -90,32 +90,32 @@ handle_drain_profits_finished (void *cls, case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dr.hr.ec = TALER_JSON_get_error_code (json); + dr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dr.hr.ec = TALER_JSON_get_error_code (json); + dr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_PRECONDITION_FAILED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dr.hr.ec = TALER_JSON_get_error_code (json); + dr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dr.hr.ec = TALER_JSON_get_error_code (json); + dr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management drain profits\n", (unsigned int) response_code, - (int) hr.ec); + (int) dr.hr.ec); break; } if (NULL != dp->cb) { dp->cb (dp->cb_cls, - &hr); + &dr); dp->cb = NULL; } TALER_EXCHANGE_management_drain_profits_cancel (dp); diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c index 80c471441..c649f397f 100644 --- a/src/lib/exchange_api_management_get_keys.c +++ b/src/lib/exchange_api_management_get_keys.c @@ -75,11 +75,16 @@ struct TALER_EXCHANGE_ManagementGetKeysHandle * @param response the response * @return #GNUNET_OK if the response was well-formed */ -static int +static enum GNUNET_GenericReturnValue handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, const json_t *response) { - struct TALER_EXCHANGE_FutureKeys fk; + struct TALER_EXCHANGE_ManagementGetKeysResponse gkr = { + .hr.http_status = MHD_HTTP_OK, + .hr.reply = response, + }; + struct TALER_EXCHANGE_FutureKeys *fk + = &gkr.details.ok.keys; json_t *sk; json_t *dk; bool ok; @@ -89,13 +94,13 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, GNUNET_JSON_spec_json ("future_signkeys", &sk), GNUNET_JSON_spec_fixed_auto ("master_pub", - &fk.master_pub), + &fk->master_pub), GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key", - &fk.denom_secmod_public_key), + &fk->denom_secmod_public_key), GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key", - &fk.denom_secmod_cs_public_key), + &fk->denom_secmod_cs_public_key), GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key", - &fk.signkey_secmod_public_key), + &fk->signkey_secmod_public_key), GNUNET_JSON_spec_end () }; @@ -107,21 +112,21 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, GNUNET_break_op (0); return GNUNET_SYSERR; } - fk.num_sign_keys = json_array_size (sk); - fk.num_denom_keys = json_array_size (dk); - fk.sign_keys = GNUNET_new_array ( - fk.num_sign_keys, + fk->num_sign_keys = json_array_size (sk); + fk->num_denom_keys = json_array_size (dk); + fk->sign_keys = GNUNET_new_array ( + fk->num_sign_keys, struct TALER_EXCHANGE_FutureSigningPublicKey); - fk.denom_keys = GNUNET_new_array ( - fk.num_denom_keys, + fk->denom_keys = GNUNET_new_array ( + fk->num_denom_keys, struct TALER_EXCHANGE_FutureDenomPublicKey); ok = true; - for (unsigned int i = 0; inum_sign_keys; i++) { json_t *j = json_array_get (sk, i); struct TALER_EXCHANGE_FutureSigningPublicKey *sign_key - = &fk.sign_keys[i]; + = &fk->sign_keys[i]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("key", &sign_key->key), @@ -155,7 +160,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, &sign_key->key, sign_key->valid_from, duration, - &fk.signkey_secmod_public_key, + &fk->signkey_secmod_public_key, &sign_key->signkey_secmod_sig)) { GNUNET_break_op (0); @@ -164,12 +169,12 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, } } } - for (unsigned int i = 0; inum_denom_keys; i++) { json_t *j = json_array_get (dk, i); struct TALER_EXCHANGE_FutureDenomPublicKey *denom_key - = &fk.denom_keys[i]; + = &fk->denom_keys[i]; const char *section_name; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount_any ("value", @@ -236,7 +241,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, section_name, denom_key->valid_from, duration, - &fk.denom_secmod_public_key, + &fk->denom_secmod_public_key, &denom_key->denom_secmod_sig)) { GNUNET_break_op (0); @@ -256,7 +261,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, section_name, denom_key->valid_from, duration, - &fk.denom_secmod_cs_public_key, + &fk->denom_secmod_cs_public_key, &denom_key->denom_secmod_sig)) { GNUNET_break_op (0); @@ -277,19 +282,13 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, } if (ok) { - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = MHD_HTTP_OK, - .reply = response - }; - gh->cb (gh->cb_cls, - &hr, - &fk); + &gkr); } - for (unsigned int i = 0; inum_denom_keys; i++) + TALER_denom_pub_free (&fk->denom_keys[i].key); + GNUNET_free (fk->sign_keys); + GNUNET_free (fk->denom_keys); GNUNET_JSON_parse_free (spec); return (ok) ? GNUNET_OK : GNUNET_SYSERR; } @@ -310,9 +309,9 @@ handle_get_keys_finished (void *cls, { struct TALER_EXCHANGE_ManagementGetKeysHandle *gh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementGetKeysResponse gkr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; gh->job = NULL; @@ -334,25 +333,24 @@ handle_get_keys_finished (void *cls, /* unexpected response code */ if (NULL != json) { - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + gkr.hr.ec = TALER_JSON_get_error_code (json); + gkr.hr.hint = TALER_JSON_get_error_hint (json); } else { - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = TALER_ErrorCode_get_hint (hr.ec); + gkr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + gkr.hr.hint = TALER_ErrorCode_get_hint (gkr.hr.ec); } GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management get keys\n", (unsigned int) response_code, - (int) hr.ec); + (int) gkr.hr.ec); break; } if (NULL != gh->cb) { gh->cb (gh->cb_cls, - &hr, - NULL); + &gkr); gh->cb = NULL; } TALER_EXCHANGE_get_management_keys_cancel (gh); diff --git a/src/lib/exchange_api_management_post_extensions.c b/src/lib/exchange_api_management_post_extensions.c index abec4ef09..b9721a982 100644 --- a/src/lib/exchange_api_management_post_extensions.c +++ b/src/lib/exchange_api_management_post_extensions.c @@ -83,9 +83,9 @@ handle_post_extensions_finished (void *cls, { struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementPostExtensionsResponse per = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; ph->job = NULL; @@ -94,28 +94,28 @@ handle_post_extensions_finished (void *cls, case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + per.hr.ec = TALER_JSON_get_error_code (json); + per.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + per.hr.ec = TALER_JSON_get_error_code (json); + per.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + per.hr.ec = TALER_JSON_get_error_code (json); + per.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management post extensions\n", (unsigned int) response_code, - (int) hr.ec); + (int) per.hr.ec); break; } if (NULL != ph->cb) { ph->cb (ph->cb_cls, - &hr); + &per); ph->cb = NULL; } TALER_EXCHANGE_management_post_extensions_cancel (ph); diff --git a/src/lib/exchange_api_management_post_keys.c b/src/lib/exchange_api_management_post_keys.c index 291c0ac02..a46124d90 100644 --- a/src/lib/exchange_api_management_post_keys.c +++ b/src/lib/exchange_api_management_post_keys.c @@ -82,9 +82,9 @@ handle_post_keys_finished (void *cls, { struct TALER_EXCHANGE_ManagementPostKeysHandle *ph = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementPostKeysResponse pkr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; ph->job = NULL; @@ -93,32 +93,32 @@ handle_post_keys_finished (void *cls, case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pkr.hr.ec = TALER_JSON_get_error_code (json); + pkr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pkr.hr.ec = TALER_JSON_get_error_code (json); + pkr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_REQUEST_ENTITY_TOO_LARGE: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pkr.hr.ec = TALER_JSON_get_error_code (json); + pkr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pkr.hr.ec = TALER_JSON_get_error_code (json); + pkr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management post keys\n", (unsigned int) response_code, - (int) hr.ec); + (int) pkr.hr.ec); break; } if (NULL != ph->cb) { ph->cb (ph->cb_cls, - &hr); + &pkr); ph->cb = NULL; } TALER_EXCHANGE_post_management_keys_cancel (ph); diff --git a/src/lib/exchange_api_management_revoke_denomination_key.c b/src/lib/exchange_api_management_revoke_denomination_key.c index 8d65b6451..aa4d527a7 100644 --- a/src/lib/exchange_api_management_revoke_denomination_key.c +++ b/src/lib/exchange_api_management_revoke_denomination_key.c @@ -82,9 +82,9 @@ handle_revoke_denomination_finished (void *cls, { struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementRevokeDenominationResponse rdr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; rh->job = NULL; @@ -92,30 +92,30 @@ handle_revoke_denomination_finished (void *cls, { case 0: /* no reply */ - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = "server offline?"; + rdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + rdr.hr.hint = "server offline?"; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + rdr.hr.ec = TALER_JSON_get_error_code (json); + rdr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + rdr.hr.ec = TALER_JSON_get_error_code (json); + rdr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management revoke denomination\n", (unsigned int) response_code, - (int) hr.ec); + (int) rdr.hr.ec); break; } if (NULL != rh->cb) { rh->cb (rh->cb_cls, - &hr); + &rdr); rh->cb = NULL; } TALER_EXCHANGE_management_revoke_denomination_key_cancel (rh); diff --git a/src/lib/exchange_api_management_revoke_signing_key.c b/src/lib/exchange_api_management_revoke_signing_key.c index aac27678f..c4d634248 100644 --- a/src/lib/exchange_api_management_revoke_signing_key.c +++ b/src/lib/exchange_api_management_revoke_signing_key.c @@ -79,9 +79,9 @@ handle_revoke_signing_finished (void *cls, { struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse rsr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; rh->job = NULL; @@ -89,30 +89,30 @@ handle_revoke_signing_finished (void *cls, { case 0: /* no reply */ - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = "server offline?"; + rsr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + rsr.hr.hint = "server offline?"; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + rsr.hr.ec = TALER_JSON_get_error_code (json); + rsr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + rsr.hr.ec = TALER_JSON_get_error_code (json); + rsr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management revoke signkey\n", (unsigned int) response_code, - (int) hr.ec); + (int) rsr.hr.ec); break; } if (NULL != rh->cb) { rh->cb (rh->cb_cls, - &hr); + &rsr); rh->cb = NULL; } TALER_EXCHANGE_management_revoke_signing_key_cancel (rh); diff --git a/src/lib/exchange_api_management_update_aml_officer.c b/src/lib/exchange_api_management_update_aml_officer.c index 6e1669465..0033a1308 100644 --- a/src/lib/exchange_api_management_update_aml_officer.c +++ b/src/lib/exchange_api_management_update_aml_officer.c @@ -79,9 +79,9 @@ handle_update_aml_officer_finished (void *cls, { struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse uar = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; wh->job = NULL; @@ -89,34 +89,34 @@ handle_update_aml_officer_finished (void *cls, { case 0: /* no reply */ - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = "server offline?"; + uar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + uar.hr.hint = "server offline?"; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + uar.hr.ec = TALER_JSON_get_error_code (json); + uar.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + uar.hr.ec = TALER_JSON_get_error_code (json); + uar.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + uar.hr.ec = TALER_JSON_get_error_code (json); + uar.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management update AML officer\n", (unsigned int) response_code, - (int) hr.ec); + (int) uar.hr.ec); break; } if (NULL != wh->cb) { wh->cb (wh->cb_cls, - &hr); + &uar); wh->cb = NULL; } TALER_EXCHANGE_management_update_aml_officer_cancel (wh); diff --git a/src/lib/exchange_api_management_wire_disable.c b/src/lib/exchange_api_management_wire_disable.c index 5d97eef75..30a010762 100644 --- a/src/lib/exchange_api_management_wire_disable.c +++ b/src/lib/exchange_api_management_wire_disable.c @@ -79,9 +79,9 @@ handle_auditor_disable_finished (void *cls, { struct TALER_EXCHANGE_ManagementWireDisableHandle *wh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementWireDisableResponse wdr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; wh->job = NULL; @@ -89,38 +89,38 @@ handle_auditor_disable_finished (void *cls, { case 0: /* no reply */ - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = "server offline?"; + wdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wdr.hr.hint = "server offline?"; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wdr.hr.ec = TALER_JSON_get_error_code (json); + wdr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wdr.hr.ec = TALER_JSON_get_error_code (json); + wdr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wdr.hr.ec = TALER_JSON_get_error_code (json); + wdr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wdr.hr.ec = TALER_JSON_get_error_code (json); + wdr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d exchange management disable wire\n", (unsigned int) response_code, - (int) hr.ec); + (int) wdr.hr.ec); break; } if (NULL != wh->cb) { wh->cb (wh->cb_cls, - &hr); + &wdr); wh->cb = NULL; } TALER_EXCHANGE_management_disable_wire_cancel (wh); diff --git a/src/lib/exchange_api_management_wire_enable.c b/src/lib/exchange_api_management_wire_enable.c index 55480474e..23a98b153 100644 --- a/src/lib/exchange_api_management_wire_enable.c +++ b/src/lib/exchange_api_management_wire_enable.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2021 Taler Systems SA + Copyright (C) 2015-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -79,9 +79,9 @@ handle_auditor_enable_finished (void *cls, { struct TALER_EXCHANGE_ManagementWireEnableHandle *wh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementWireEnableResponse wer = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; wh->job = NULL; @@ -89,34 +89,34 @@ handle_auditor_enable_finished (void *cls, { case 0: /* no reply */ - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = "server offline?"; + wer.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wer.hr.hint = "server offline?"; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wer.hr.ec = TALER_JSON_get_error_code (json); + wer.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wer.hr.ec = TALER_JSON_get_error_code (json); + wer.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wer.hr.ec = TALER_JSON_get_error_code (json); + wer.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management enable wire\n", (unsigned int) response_code, - (int) hr.ec); + (int) wer.hr.ec); break; } if (NULL != wh->cb) { wh->cb (wh->cb_cls, - &hr); + &wer); wh->cb = NULL; } TALER_EXCHANGE_management_enable_wire_cancel (wh); @@ -128,6 +128,9 @@ TALER_EXCHANGE_management_enable_wire ( struct GNUNET_CURL_Context *ctx, const char *url, const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp validity_start, const struct TALER_MasterSignatureP *master_sig1, const struct TALER_MasterSignatureP *master_sig2, @@ -167,6 +170,13 @@ TALER_EXCHANGE_management_enable_wire ( body = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("payto_uri", payto_uri), + GNUNET_JSON_pack_array_incref ("debit_restrictions", + (json_t *) debit_restrictions), + GNUNET_JSON_pack_array_incref ("credit_restrictions", + (json_t *) credit_restrictions), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("conversion_url", + conversion_url)), GNUNET_JSON_pack_data_auto ("master_sig_add", master_sig1), GNUNET_JSON_pack_data_auto ("master_sig_wire", diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index feeef4001..3a8144a3c 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -221,16 +221,16 @@ handle_melt_finished (void *cls, if (GNUNET_OK != verify_melt_signature_ok (mh, j, - &mr.details.success.sign_key)) + &mr.details.ok.sign_key)) { GNUNET_break_op (0); mr.hr.http_status = 0; mr.hr.ec = TALER_EC_EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE; break; } - mr.details.success.noreveal_index = mh->noreveal_index; - mr.details.success.num_mbds = mh->rd->fresh_pks_len; - mr.details.success.mbds = mh->mbds; + mr.details.ok.noreveal_index = mh->noreveal_index; + mr.details.ok.num_mbds = mh->rd->fresh_pks_len; + mr.details.ok.mbds = mh->mbds; mh->melt_cb (mh->melt_cb_cls, &mr); mh->melt_cb = NULL; @@ -478,7 +478,7 @@ csr_cb (void *cls, break; case TALER_DENOMINATION_CS: GNUNET_assert (TALER_DENOMINATION_CS == wv->cipher); - *wv = csrr->details.success.alg_values[nks_off]; + *wv = csrr->details.ok.alg_values[nks_off]; nks_off++; break; } diff --git a/src/lib/exchange_api_purse_deposit.c b/src/lib/exchange_api_purse_deposit.c index f5a503b0b..f88d23299 100644 --- a/src/lib/exchange_api_purse_deposit.c +++ b/src/lib/exchange_api_purse_deposit.c @@ -164,17 +164,17 @@ handle_purse_deposit_finished (void *cls, GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", - &dr.details.success.h_contract_terms), + &dr.details.ok.h_contract_terms), GNUNET_JSON_spec_timestamp ("exchange_timestamp", &etime), GNUNET_JSON_spec_timestamp ("purse_expiration", - &dr.details.success.purse_expiration), + &dr.details.ok.purse_expiration), TALER_JSON_spec_amount ("total_deposited", keys->currency, - &dr.details.success.total_deposited), + &dr.details.ok.total_deposited), TALER_JSON_spec_amount ("purse_value_after_fees", keys->currency, - &dr.details.success.purse_value_after_fees), + &dr.details.ok.purse_value_after_fees), GNUNET_JSON_spec_end () }; @@ -200,11 +200,11 @@ handle_purse_deposit_finished (void *cls, if (GNUNET_OK != TALER_exchange_online_purse_created_verify ( etime, - dr.details.success.purse_expiration, - &dr.details.success.purse_value_after_fees, - &dr.details.success.total_deposited, + dr.details.ok.purse_expiration, + &dr.details.ok.purse_value_after_fees, + &dr.details.ok.total_deposited, &pch->purse_pub, - &dr.details.success.h_contract_terms, + &dr.details.ok.h_contract_terms, &exchange_pub, &exchange_sig)) { diff --git a/src/lib/exchange_api_purse_merge.c b/src/lib/exchange_api_purse_merge.c index fd11978d9..6e1995e0d 100644 --- a/src/lib/exchange_api_purse_merge.c +++ b/src/lib/exchange_api_purse_merge.c @@ -152,11 +152,11 @@ handle_purse_merge_finished (void *cls, struct TALER_Amount total_deposited; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", - &dr.details.success.exchange_sig), + &dr.details.ok.exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", - &dr.details.success.exchange_pub), + &dr.details.ok.exchange_pub), GNUNET_JSON_spec_timestamp ("exchange_timestamp", - &dr.details.success.etime), + &dr.details.ok.etime), TALER_JSON_spec_amount ("merge_amount", pch->purse_value_after_fees.currency, &total_deposited), @@ -176,7 +176,7 @@ handle_purse_merge_finished (void *cls, key_state = TALER_EXCHANGE_get_keys (pch->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &dr.details.success.exchange_pub)) + &dr.details.ok.exchange_pub)) { GNUNET_break_op (0); dr.hr.http_status = 0; @@ -185,15 +185,15 @@ handle_purse_merge_finished (void *cls, } if (GNUNET_OK != TALER_exchange_online_purse_merged_verify ( - dr.details.success.etime, + dr.details.ok.etime, pch->purse_expiration, &pch->purse_value_after_fees, &pch->purse_pub, &pch->h_contract_terms, &pch->reserve_pub, pch->provider_url, - &dr.details.success.exchange_pub, - &dr.details.success.exchange_sig)) + &dr.details.ok.exchange_pub, + &dr.details.ok.exchange_sig)) { GNUNET_break_op (0); dr.hr.http_status = 0; diff --git a/src/lib/exchange_api_purses_get.c b/src/lib/exchange_api_purses_get.c index 5d63ecf13..4c2fdd79c 100644 --- a/src/lib/exchange_api_purses_get.c +++ b/src/lib/exchange_api_purses_get.c @@ -101,16 +101,16 @@ handle_purse_get_finished (void *cls, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("merge_timestamp", - &dr.details.success.merge_timestamp), + &dr.details.ok.merge_timestamp), &no_merge), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("deposit_timestamp", - &dr.details.success.deposit_timestamp), + &dr.details.ok.deposit_timestamp), &no_deposit), TALER_JSON_spec_amount_any ("balance", - &dr.details.success.balance), + &dr.details.ok.balance), GNUNET_JSON_spec_timestamp ("purse_expiration", - &dr.details.success.purse_expiration), + &dr.details.ok.purse_expiration), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_fixed_auto ("exchange_sig", @@ -142,9 +142,9 @@ handle_purse_get_finished (void *cls, } if (GNUNET_OK != TALER_exchange_online_purse_status_verify ( - dr.details.success.merge_timestamp, - dr.details.success.deposit_timestamp, - &dr.details.success.balance, + dr.details.ok.merge_timestamp, + dr.details.ok.deposit_timestamp, + &dr.details.ok.balance, &exchange_pub, &exchange_sig)) { diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c index 8de4da123..b89bda8b3 100644 --- a/src/lib/exchange_api_recoup.c +++ b/src/lib/exchange_api_recoup.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2017-2022 Taler Systems SA + Copyright (C) 2017-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -100,16 +100,15 @@ static enum GNUNET_GenericReturnValue process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph, const json_t *json) { - struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_EXCHANGE_RecoupResponse rr = { + .hr.reply = json, + .hr.http_status = MHD_HTTP_OK + }; struct GNUNET_JSON_Specification spec_withdraw[] = { GNUNET_JSON_spec_fixed_auto ("reserve_pub", - &reserve_pub), + &rr.details.ok.reserve_pub), GNUNET_JSON_spec_end () }; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = json, - .http_status = MHD_HTTP_OK - }; if (GNUNET_OK != GNUNET_JSON_parse (json, @@ -120,8 +119,7 @@ process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph, return GNUNET_SYSERR; } ph->cb (ph->cb_cls, - &hr, - &reserve_pub); + &rr); return GNUNET_OK; } @@ -141,9 +139,9 @@ handle_recoup_finished (void *cls, { struct TALER_EXCHANGE_RecoupHandle *ph = cls; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_RecoupResponse rr = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; const struct TALER_EXCHANGE_Keys *keys; @@ -152,7 +150,7 @@ handle_recoup_finished (void *cls, switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: if (GNUNET_OK != @@ -160,8 +158,8 @@ handle_recoup_finished (void *cls, j)) { GNUNET_break_op (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + rr.hr.http_status = 0; break; } TALER_EXCHANGE_recoup_cancel (ph); @@ -169,22 +167,22 @@ handle_recoup_finished (void *cls, case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_CONFLICT: { struct TALER_Amount min_key; - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); if (GNUNET_OK != TALER_EXCHANGE_get_min_denomination_ (keys, &min_key)) { GNUNET_break (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + rr.hr.http_status = 0; break; } if (GNUNET_OK != @@ -197,8 +195,8 @@ handle_recoup_finished (void *cls, &min_key)) { GNUNET_break (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + rr.hr.http_status = 0; break; } break; @@ -207,41 +205,40 @@ handle_recoup_finished (void *cls, /* Nothing really to verify, exchange says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_GONE: /* Kind of normal: the money was already sent to the merchant (it was too late for the refund). */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange recoup\n", (unsigned int) response_code, - (int) hr.ec); + (int) rr.hr.ec); GNUNET_break (0); break; } ph->cb (ph->cb_cls, - &hr, - NULL); + &rr); TALER_EXCHANGE_recoup_cancel (ph); } diff --git a/src/lib/exchange_api_recoup_refresh.c b/src/lib/exchange_api_recoup_refresh.c index 00eeca070..7b42aa7eb 100644 --- a/src/lib/exchange_api_recoup_refresh.c +++ b/src/lib/exchange_api_recoup_refresh.c @@ -101,16 +101,15 @@ process_recoup_response ( const struct TALER_EXCHANGE_RecoupRefreshHandle *ph, const json_t *json) { - struct TALER_CoinSpendPublicKeyP old_coin_pub; + struct TALER_EXCHANGE_RecoupRefreshResponse rrr = { + .hr.reply = json, + .hr.http_status = MHD_HTTP_OK + }; struct GNUNET_JSON_Specification spec_refresh[] = { GNUNET_JSON_spec_fixed_auto ("old_coin_pub", - &old_coin_pub), + &rrr.details.ok.old_coin_pub), GNUNET_JSON_spec_end () }; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = json, - .http_status = MHD_HTTP_OK - }; if (GNUNET_OK != GNUNET_JSON_parse (json, @@ -121,8 +120,7 @@ process_recoup_response ( return GNUNET_SYSERR; } ph->cb (ph->cb_cls, - &hr, - &old_coin_pub); + &rrr); return GNUNET_OK; } @@ -142,9 +140,9 @@ handle_recoup_refresh_finished (void *cls, { struct TALER_EXCHANGE_RecoupRefreshHandle *ph = cls; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_RecoupRefreshResponse rrr = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; const struct TALER_EXCHANGE_Keys *keys; @@ -153,7 +151,7 @@ handle_recoup_refresh_finished (void *cls, switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + rrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: if (GNUNET_OK != @@ -161,8 +159,8 @@ handle_recoup_refresh_finished (void *cls, j)) { GNUNET_break_op (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + rrr.hr.http_status = 0; break; } TALER_EXCHANGE_recoup_refresh_cancel (ph); @@ -170,35 +168,35 @@ handle_recoup_refresh_finished (void *cls, case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, exchange says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_CONFLICT: { struct TALER_Amount min_key; - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); if (GNUNET_OK != TALER_EXCHANGE_get_min_denomination_ (keys, &min_key)) { GNUNET_break (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + rrr.hr.http_status = 0; break; } if (GNUNET_OK != @@ -211,8 +209,8 @@ handle_recoup_refresh_finished (void *cls, &min_key)) { GNUNET_break (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + rrr.hr.http_status = 0; break; } break; @@ -220,29 +218,28 @@ handle_recoup_refresh_finished (void *cls, case MHD_HTTP_GONE: /* Kind of normal: the money was already sent to the merchant (it was too late for the refund). */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rrr.hr.ec = TALER_JSON_get_error_code (j); + rrr.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange recoup\n", (unsigned int) response_code, - (int) hr.ec); + (int) rrr.hr.ec); GNUNET_break (0); break; } ph->cb (ph->cb_cls, - &hr, - NULL); + &rrr); TALER_EXCHANGE_recoup_refresh_cancel (ph); } diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index cd2a1d1f4..3bdef2020 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -266,8 +266,8 @@ handle_refresh_reveal_finished (void *cls, else { GNUNET_assert (rrh->noreveal_index < TALER_CNC_KAPPA); - rr.details.success.num_coins = rrh->md.num_fresh_coins; - rr.details.success.coins = rcis; + rr.details.ok.num_coins = rrh->md.num_fresh_coins; + rr.details.ok.coins = rcis; rrh->reveal_cb (rrh->reveal_cb_cls, &rr); rrh->reveal_cb = NULL; diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 855b4fcc7..7c9616ea5 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -585,37 +585,28 @@ handle_refund_finished (void *cls, const void *response) { struct TALER_EXCHANGE_RefundHandle *rh = cls; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP *ep = NULL; - struct TALER_ExchangeSignatureP *es = NULL; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_RefundResponse rr = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; rh->job = NULL; switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: if (GNUNET_OK != verify_refund_signature_ok (rh, j, - &exchange_pub, - &exchange_sig)) + &rr.details.ok.exchange_pub, + &rr.details.ok.exchange_sig)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE; - } - else - { - ep = &exchange_pub; - es = &exchange_sig; + rr.hr.http_status = 0; + rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE; } break; case MHD_HTTP_BAD_REQUEST: @@ -623,21 +614,21 @@ handle_refund_finished (void *cls, (or API version conflict); also can happen if the currency differs (which we should obviously never support). Just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, exchange says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_CONFLICT: /* Requested total refunds exceed deposited amount */ @@ -649,19 +640,19 @@ handle_refund_finished (void *cls, json_dumpf (j, stderr, JSON_INDENT (2)); - hr.http_status = 0; - hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE; - hr.hint = "conflict information provided by exchange is invalid"; + rr.hr.http_status = 0; + rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE; + rr.hr.hint = "conflict information provided by exchange is invalid"; break; } - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_GONE: /* Kind of normal: the money was already sent to the merchant (it was too late for the refund). */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_PRECONDITION_FAILED: if (GNUNET_OK != @@ -669,37 +660,35 @@ handle_refund_finished (void *cls, j)) { GNUNET_break (0); - hr.http_status = 0; - hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE; - hr.hint = "failed precondition proof returned by exchange is invalid"; + rr.hr.http_status = 0; + rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE; + rr.hr.hint = "failed precondition proof returned by exchange is invalid"; break; } /* Two different refund requests were made about the same deposit, but carrying identical refund transaction ids. */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + rr.hr.ec = TALER_JSON_get_error_code (j); + rr.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange refund\n", (unsigned int) response_code, - hr.ec); + rr.hr.ec); break; } rh->cb (rh->cb_cls, - &hr, - ep, - es); + &rr); TALER_EXCHANGE_refund_cancel (rh); } diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index 06465618c..c2a1c0b15 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -85,23 +85,32 @@ check_transfers_get_response_ok ( const json_t *json) { json_t *details_j; - struct TALER_EXCHANGE_TransferData td; struct TALER_Amount total_expected; struct TALER_MerchantPublicKeyP merchant_pub; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any ("total", &td.total_amount), - TALER_JSON_spec_amount_any ("wire_fee", &td.wire_fee), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), - GNUNET_JSON_spec_fixed_auto ("h_payto", &td.h_payto), - GNUNET_JSON_spec_timestamp ("execution_time", &td.execution_time), - GNUNET_JSON_spec_json ("deposits", &details_j), - GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub), - GNUNET_JSON_spec_end () + struct TALER_EXCHANGE_TransfersGetResponse tgr = { + .hr.reply = json, + .hr.http_status = MHD_HTTP_OK }; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = json, - .http_status = MHD_HTTP_OK + struct TALER_EXCHANGE_TransferData *td + = &tgr.details.ok.td; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount_any ("total", + &td->total_amount), + TALER_JSON_spec_amount_any ("wire_fee", + &td->wire_fee), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &merchant_pub), + GNUNET_JSON_spec_fixed_auto ("h_payto", + &td->h_payto), + GNUNET_JSON_spec_timestamp ("execution_time", + &td->execution_time), + GNUNET_JSON_spec_json ("deposits", + &details_j), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", + &td->exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", + &td->exchange_pub), + GNUNET_JSON_spec_end () }; if (GNUNET_OK != @@ -113,7 +122,7 @@ check_transfers_get_response_ok ( return GNUNET_SYSERR; } if (GNUNET_OK != - TALER_amount_set_zero (td.total_amount.currency, + TALER_amount_set_zero (td->total_amount.currency, &total_expected)) { GNUNET_break_op (0); @@ -123,22 +132,22 @@ check_transfers_get_response_ok ( if (GNUNET_OK != TALER_EXCHANGE_test_signing_key ( TALER_EXCHANGE_get_keys (wdh->exchange), - &td.exchange_pub)) + &td->exchange_pub)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - td.details_length = json_array_size (details_j); + td->details_length = json_array_size (details_j); { struct GNUNET_HashContext *hash_context; struct TALER_TrackTransferDetails *details; - details = GNUNET_new_array (td.details_length, + details = GNUNET_new_array (td->details_length, struct TALER_TrackTransferDetails); - td.details = details; + td->details = details; hash_context = GNUNET_CRYPTO_hash_context_start (); - for (unsigned int i = 0; idetails_length; i++) { struct TALER_TrackTransferDetails *detail = &details[i]; struct json_t *detail_j = json_array_get (details_j, i); @@ -180,7 +189,7 @@ check_transfers_get_response_ok ( TALER_exchange_online_wire_deposit_append ( hash_context, &detail->h_contract_terms, - td.execution_time, + td->execution_time, &detail->coin_pub, &detail->coin_value, &detail->coin_fee); @@ -193,13 +202,13 @@ check_transfers_get_response_ok ( &h_details); if (GNUNET_OK != TALER_exchange_online_wire_deposit_verify ( - &td.total_amount, - &td.wire_fee, + &td->total_amount, + &td->wire_fee, &merchant_pub, - &td.h_payto, + &td->h_payto, &h_details, - &td.exchange_pub, - &td.exchange_sig)) + &td->exchange_pub, + &td->exchange_sig)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -211,7 +220,7 @@ check_transfers_get_response_ok ( if (0 > TALER_amount_subtract (&total_expected, &total_expected, - &td.wire_fee)) + &td->wire_fee)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -220,7 +229,7 @@ check_transfers_get_response_ok ( } if (0 != TALER_amount_cmp (&total_expected, - &td.total_amount)) + &td->total_amount)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -228,8 +237,7 @@ check_transfers_get_response_ok ( return GNUNET_SYSERR; } wdh->cb (wdh->cb_cls, - &hr, - &td); + &tgr); GNUNET_free (details); } GNUNET_JSON_parse_free (spec); @@ -253,16 +261,16 @@ handle_transfers_get_finished (void *cls, { struct TALER_EXCHANGE_TransfersGetHandle *wdh = cls; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_TransfersGetResponse tgr = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; wdh->job = NULL; switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: if (GNUNET_OK == @@ -270,48 +278,47 @@ handle_transfers_get_finished (void *cls, j)) return; GNUNET_break_op (0); - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - hr.http_status = 0; + tgr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + tgr.hr.http_status = 0; break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + tgr.hr.ec = TALER_JSON_get_error_code (j); + tgr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, exchange says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + tgr.hr.ec = TALER_JSON_get_error_code (j); + tgr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Exchange does not know about transaction; we should pass the reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + tgr.hr.ec = TALER_JSON_get_error_code (j); + tgr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + tgr.hr.ec = TALER_JSON_get_error_code (j); + tgr.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + tgr.hr.ec = TALER_JSON_get_error_code (j); + tgr.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for transfers get\n", (unsigned int) response_code, - (int) hr.ec); + (int) tgr.hr.ec); break; } wdh->cb (wdh->cb_cls, - &hr, - NULL); + &tgr); TALER_EXCHANGE_transfers_get_cancel (wdh); } diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c index c23ea62d8..498265282 100644 --- a/src/lib/exchange_api_wire.c +++ b/src/lib/exchange_api_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -66,82 +66,65 @@ struct TALER_EXCHANGE_WireHandle /** - * List of wire fees by method. - */ -struct FeeMap -{ - /** - * Next entry in list. - */ - struct FeeMap *next; - - /** - * Wire method this fee structure is for. - */ - char *method; - - /** - * Array of wire fees, also linked list, but allocated - * only once. - */ - struct TALER_EXCHANGE_WireAggregateFees *fee_list; -}; - - -/** - * Frees @a fm. + * Frees @a wfm array. * - * @param fm memory to release + * @param wfm fee array to release + * @param wfm_len length of the @a wfm array */ static void -free_fees (struct FeeMap *fm) +free_fees (struct TALER_EXCHANGE_WireFeesByMethod *wfm, + unsigned int wfm_len) { - while (NULL != fm) + for (unsigned int i = 0; inext; + struct TALER_EXCHANGE_WireFeesByMethod *wfmi = &wfm[i]; - GNUNET_free (fm->fee_list); - GNUNET_free (fm->method); - GNUNET_free (fm); - fm = fe; + while (NULL != wfmi->fees_head) + { + struct TALER_EXCHANGE_WireAggregateFees *fe + = wfmi->fees_head; + + wfmi->fees_head = fe->next; + GNUNET_free (fe); + } } + GNUNET_free (wfm); } /** - * Parse wire @a fees and return map. + * Parse wire @a fees and return array. * * @param master_pub master public key to use to check signatures * @param fees json AggregateTransferFee to parse + * @param[out] fees_len set to length of returned array * @return NULL on error */ -static struct FeeMap * +static struct TALER_EXCHANGE_WireFeesByMethod * parse_fees (const struct TALER_MasterPublicKeyP *master_pub, - json_t *fees) + const json_t *fees, + unsigned int *fees_len) { - struct FeeMap *fm = NULL; + struct TALER_EXCHANGE_WireFeesByMethod *fbm; + unsigned int fbml = json_object_size (fees); + unsigned int i = 0; const char *key; - json_t *fee_array; + const json_t *fee_array; - json_object_foreach (fees, key, fee_array) { - struct FeeMap *fe = GNUNET_new (struct FeeMap); - unsigned int len; + fbm = GNUNET_new_array (fbml, + struct TALER_EXCHANGE_WireFeesByMethod); + *fees_len = fbml; + json_object_foreach ((json_t *) fees, key, fee_array) { + struct TALER_EXCHANGE_WireFeesByMethod *fe = &fbm[i++]; unsigned int idx; json_t *fee; - if (0 == (len = json_array_size (fee_array))) - { - GNUNET_free (fe); - continue; /* skip */ - } - fe->method = GNUNET_strdup (key); - fe->next = fm; - fe->fee_list = GNUNET_new_array (len, - struct TALER_EXCHANGE_WireAggregateFees); - fm = fe; + fe->method = key; + fe->fees_head = NULL; json_array_foreach (fee_array, idx, fee) { - struct TALER_EXCHANGE_WireAggregateFees *wa = &fe->fee_list[idx]; + struct TALER_EXCHANGE_WireAggregateFees *wa + = GNUNET_new (struct TALER_EXCHANGE_WireAggregateFees); struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("sig", &wa->master_sig), @@ -156,6 +139,8 @@ parse_fees (const struct TALER_MasterPublicKeyP *master_pub, GNUNET_JSON_spec_end () }; + wa->next = fe->fees_head; + fe->fees_head = wa; if (GNUNET_OK != GNUNET_JSON_parse (fee, spec, @@ -163,7 +148,8 @@ parse_fees (const struct TALER_MasterPublicKeyP *master_pub, NULL)) { GNUNET_break_op (0); - free_fees (fm); + free_fees (fbm, + i); return NULL; } if (GNUNET_OK != @@ -176,35 +162,122 @@ parse_fees (const struct TALER_MasterPublicKeyP *master_pub, &wa->master_sig)) { GNUNET_break_op (0); - free_fees (fm); + free_fees (fbm, + i); return NULL; } - if (idx + 1 < len) - wa->next = &fe->fee_list[idx + 1]; - else - wa->next = NULL; - } - } - return fm; + } /* for all fees over time */ + } /* for all methods */ + GNUNET_assert (i == fbml); + return fbm; } /** - * Find fee by @a method. + * Parse account restriction in @a jrest into @a rest. * - * @param fm map to look in - * @param method key to look for - * @return NULL if fee is not specified in @a fm + * @param jrest array of account restrictions in JSON + * @param[out] resta_len set to length of @a resta + * @param[out] resta account restriction array to set + * @return #GNUNET_OK on success */ -static const struct TALER_EXCHANGE_WireAggregateFees * -lookup_fee (const struct FeeMap *fm, - const char *method) +static enum GNUNET_GenericReturnValue +parse_restrictions (const json_t *jresta, + unsigned int *resta_len, + struct TALER_EXCHANGE_AccountRestriction **resta) { - for (; NULL != fm; fm = fm->next) - if (0 == strcasecmp (fm->method, - method)) - return fm->fee_list; - return NULL; + if (! json_is_array (jresta)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + *resta_len = json_array_size (jresta); + if (0 == *resta_len) + { + /* no restrictions, perfectly OK */ + *resta = NULL; + return GNUNET_OK; + } + *resta = GNUNET_new_array (*resta_len, + struct TALER_EXCHANGE_AccountRestriction); + for (unsigned int i = 0; i<*resta_len; i++) + { + const json_t *jr = json_array_get (jresta, + i); + struct TALER_EXCHANGE_AccountRestriction *ar = &(*resta)[i]; + const char *type = json_string_value (json_object_get (jr, + "type")); + + if (NULL == type) + { + GNUNET_break (0); + goto fail; + } + if (0 == strcmp (type, + "deny")) + { + ar->type = TALER_EXCHANGE_AR_DENY; + continue; + } + if (0 == strcmp (type, + "regex")) + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ( + "payto_regex", + &ar->details.regex.posix_egrep), + GNUNET_JSON_spec_string ( + "human_hint", + &ar->details.regex.human_hint), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_object_const ( + "human_hint_i18n", + &ar->details.regex.human_hint_i18n), + NULL), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (jr, + spec, + NULL, NULL)) + { + /* bogus reply */ + GNUNET_break_op (0); + goto fail; + } + ar->type = TALER_EXCHANGE_AR_REGEX; + continue; + } + /* unsupported type */ + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +fail: + GNUNET_free (*resta); + *resta_len = 0; + return GNUNET_SYSERR; +} + + +/** + * Free data within @a was, but not @a was itself. + * + * @param was array of wire account data + * @param was_len length of the @a was array + */ +static void +free_accounts (struct TALER_EXCHANGE_WireAccount *was, + unsigned int was_len) +{ + for (unsigned int i = 0; icredit_restrictions); + GNUNET_free (wa->debit_restrictions); + } } @@ -223,9 +296,9 @@ handle_wire_finished (void *cls, { struct TALER_EXCHANGE_WireHandle *wh = cls; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_WireResponse wr = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; TALER_LOG_DEBUG ("Checking raw /wire response\n"); @@ -233,28 +306,29 @@ handle_wire_finished (void *cls, switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; wh->exchange->wire_error_count++; break; case MHD_HTTP_OK: { - json_t *accounts; - json_t *fees; - unsigned int num_accounts; - struct FeeMap *fm; + const json_t *accounts; + const json_t *fees; + const json_t *wads; + struct TALER_EXCHANGE_WireFeesByMethod *fbm; struct TALER_MasterPublicKeyP master_pub; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("master_public_key", &master_pub), - GNUNET_JSON_spec_json ("accounts", - &accounts), - GNUNET_JSON_spec_json ("fees", - &fees), + GNUNET_JSON_spec_array_const ("accounts", + &accounts), + GNUNET_JSON_spec_object_const ("fees", + &fees), + GNUNET_JSON_spec_array_const ("wads", + &wads), GNUNET_JSON_spec_end () }; wh->exchange->wire_error_count = 0; - if (GNUNET_OK != GNUNET_JSON_parse (j, spec, @@ -262,8 +336,8 @@ handle_wire_finished (void *cls, { /* bogus reply */ GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } { @@ -275,61 +349,70 @@ handle_wire_finished (void *cls, { /* bogus reply: master public key in /wire differs from that in /keys */ GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } } - if (0 == (num_accounts = json_array_size (accounts))) + wr.details.ok.accounts_len + = json_array_size (accounts); + if (0 == wr.details.ok.accounts_len) { /* bogus reply */ GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - if (NULL == (fm = parse_fees (&master_pub, - fees))) + fbm = parse_fees (&master_pub, + fees, + &wr.details.ok.fees_len); + if (NULL == fbm) { /* bogus reply */ GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } /* parse accounts */ { - struct TALER_EXCHANGE_WireAccount was[num_accounts]; + struct TALER_EXCHANGE_WireAccount was[wr.details.ok.accounts_len]; - for (unsigned int i = 0; ipayto_uri), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("conversion_url", + &wa->conversion_url), + NULL), + GNUNET_JSON_spec_json ("credit_restrictions", + &credit_restrictions), + GNUNET_JSON_spec_json ("debit_restrictions", + &debit_restrictions), GNUNET_JSON_spec_fixed_auto ("master_sig", &wa->master_sig), GNUNET_JSON_spec_end () }; - char *method; + json_t *account; account = json_array_get (accounts, i); - if (GNUNET_OK != - TALER_JSON_exchange_wire_signature_check (account, - &master_pub)) - { - /* bogus reply */ - GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_EXCHANGE_WIRE_SIGNATURE_INVALID; - break; - } if (GNUNET_OK != GNUNET_JSON_parse (account, spec_account, @@ -337,80 +420,104 @@ handle_wire_finished (void *cls, { /* bogus reply */ GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - if (NULL == (method = TALER_payto_get_method (wa->payto_uri))) + { + char *err; + + err = TALER_payto_validate (wa->payto_uri); + if (NULL != err) + { + GNUNET_break_op (0); + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + GNUNET_free (err); + break; + } + } + + if (GNUNET_OK != + TALER_exchange_wire_signature_check (wa->payto_uri, + wa->conversion_url, + debit_restrictions, + credit_restrictions, + &master_pub, + &wa->master_sig)) { /* bogus reply */ GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_EXCHANGE_WIRE_SIGNATURE_INVALID; break; } - if (NULL == (wa->fees = lookup_fee (fm, - method))) + if ( (GNUNET_OK != + parse_restrictions (credit_restrictions, + &wa->credit_restrictions_length, + &wa->credit_restrictions)) || + (GNUNET_OK != + parse_restrictions (debit_restrictions, + &wa->debit_restrictions_length, + &wa->debit_restrictions)) ) { /* bogus reply */ GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - GNUNET_free (method); + wr.hr.http_status = 0; + wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - GNUNET_free (method); + GNUNET_JSON_parse_free (spec_account); } /* end 'for all accounts */ - if ( (0 != response_code) && + if ( (0 != wr.hr.http_status) && (NULL != wh->cb) ) { wh->cb (wh->cb_cls, - &hr, - num_accounts, - was); + &wr); wh->cb = NULL; } + free_accounts (was, + wr.details.ok.accounts_len); } /* end of 'parse accounts */ - free_fees (fm); + free_fees (fbm, + wr.details.ok.fees_len); GNUNET_JSON_parse_free (spec); } /* end of MHD_HTTP_OK */ break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + wr.hr.ec = TALER_JSON_get_error_code (j); + wr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + wr.hr.ec = TALER_JSON_get_error_code (j); + wr.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + wr.hr.ec = TALER_JSON_get_error_code (j); + wr.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ if (MHD_HTTP_GATEWAY_TIMEOUT == response_code) wh->exchange->wire_error_count++; GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + wr.hr.ec = TALER_JSON_get_error_code (j); + wr.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange wire\n", (unsigned int) response_code, - (int) hr.ec); + (int) wr.hr.ec); break; } if (NULL != wh->cb) wh->cb (wh->cb_cls, - &hr, - 0, - NULL); + &wr); TALER_EXCHANGE_wire_cancel (wh); } diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c index 62c042039..2a3c095a6 100644 --- a/src/lib/exchange_api_withdraw.c +++ b/src/lib/exchange_api_withdraw.c @@ -116,22 +116,20 @@ struct TALER_EXCHANGE_WithdrawHandle * HTTP /reserves/$RESERVE_PUB/withdraw request. * * @param cls the `struct TALER_EXCHANGE_WithdrawHandle` - * @param hr HTTP response data - * @param blind_sig blind signature over the coin, NULL on error + * @param w2r response data */ static void handle_reserve_withdraw_finished ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_BlindedDenominationSignature *blind_sig) + const struct TALER_EXCHANGE_Withdraw2Response *w2r) { struct TALER_EXCHANGE_WithdrawHandle *wh = cls; struct TALER_EXCHANGE_WithdrawResponse wr = { - .hr = *hr + .hr = w2r->hr }; wh->wh2 = NULL; - switch (hr->http_status) + switch (w2r->hr.http_status) { case MHD_HTTP_OK: { @@ -139,7 +137,7 @@ handle_reserve_withdraw_finished ( if (GNUNET_OK != TALER_planchet_to_coin (&wh->pk.key, - blind_sig, + &w2r->details.ok.blind_sig, &wh->bks, &wh->priv, wh->ach, @@ -151,10 +149,10 @@ handle_reserve_withdraw_finished ( wr.hr.ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE; break; } - wr.details.success.coin_priv = wh->priv; - wr.details.success.bks = wh->bks; - wr.details.success.sig = fc.sig; - wr.details.success.exchange_vals = wh->alg_values; + wr.details.ok.coin_priv = wh->priv; + wr.details.ok.bks = wh->bks; + wr.details.ok.sig = fc.sig; + wr.details.ok.exchange_vals = wh->alg_values; break; } case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: @@ -170,7 +168,7 @@ handle_reserve_withdraw_finished ( }; if (GNUNET_OK != - GNUNET_JSON_parse (hr->reply, + GNUNET_JSON_parse (w2r->hr.reply, spec, NULL, NULL)) { @@ -186,8 +184,8 @@ handle_reserve_withdraw_finished ( } wh->cb (wh->cb_cls, &wr); - if (MHD_HTTP_OK == hr->http_status) - TALER_denom_sig_free (&wr.details.success.sig); + if (MHD_HTTP_OK == w2r->hr.http_status) + TALER_denom_sig_free (&wr.details.ok.sig); TALER_EXCHANGE_withdraw_cancel (wh); } @@ -213,7 +211,7 @@ withdraw_cs_stage_two_callback ( switch (csrr->hr.http_status) { case MHD_HTTP_OK: - wh->alg_values = csrr->details.success.alg_values; + wh->alg_values = csrr->details.ok.alg_values; TALER_planchet_setup_coin_priv (&wh->ps, &wh->alg_values, &wh->priv); diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index 04881804a..bf2bd0237 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -99,16 +99,15 @@ static enum GNUNET_GenericReturnValue reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh, const json_t *json) { - struct TALER_BlindedDenominationSignature blind_sig; + struct TALER_EXCHANGE_Withdraw2Response w2r = { + .hr.reply = json, + .hr.http_status = MHD_HTTP_OK + }; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_blinded_denom_sig ("ev_sig", - &blind_sig), + &w2r.details.ok.blind_sig), GNUNET_JSON_spec_end () }; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = json, - .http_status = MHD_HTTP_OK - }; if (GNUNET_OK != GNUNET_JSON_parse (json, @@ -121,8 +120,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh, /* signature is valid, return it to the application */ wh->cb (wh->cb_cls, - &hr, - &blind_sig); + &w2r); /* make sure callback isn't called again after return */ wh->cb = NULL; GNUNET_JSON_parse_free (spec); @@ -240,16 +238,16 @@ handle_reserve_withdraw_finished (void *cls, { struct TALER_EXCHANGE_Withdraw2Handle *wh = cls; const json_t *j = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .reply = j, - .http_status = (unsigned int) response_code + struct TALER_EXCHANGE_Withdraw2Response w2r = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; wh->job = NULL; switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + w2r.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: if (GNUNET_OK != @@ -257,8 +255,8 @@ handle_reserve_withdraw_finished (void *cls, j)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + w2r.hr.http_status = 0; + w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } GNUNET_assert (NULL == wh->cb); @@ -267,24 +265,24 @@ handle_reserve_withdraw_finished (void *cls, case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_FORBIDDEN: GNUNET_break_op (0); /* Nothing really to verify, exchange says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON reply to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, the exchange basically just says that it doesn't know this reserve. Can happen if we query before the wire transfer went through. We should simply pass the JSON reply to the application. */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_CONFLICT: /* The exchange says that the reserve has insufficient funds; @@ -294,13 +292,13 @@ handle_reserve_withdraw_finished (void *cls, j)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + w2r.hr.http_status = 0; + w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; } else { - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); } break; case MHD_HTTP_GONE: @@ -308,8 +306,8 @@ handle_reserve_withdraw_finished (void *cls, /* Note: one might want to check /keys for revocation signature here, alas tricky in case our /keys is outdated => left to clients */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); break; case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: /* only validate reply is well-formed */ @@ -327,8 +325,8 @@ handle_reserve_withdraw_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + w2r.hr.http_status = 0; + w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } } @@ -336,25 +334,24 @@ handle_reserve_withdraw_finished (void *cls, case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); break; default: /* unexpected response code */ GNUNET_break_op (0); - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); + w2r.hr.ec = TALER_JSON_get_error_code (j); + w2r.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange withdraw\n", (unsigned int) response_code, - (int) hr.ec); + (int) w2r.hr.ec); break; } if (NULL != wh->cb) { wh->cb (wh->cb_cls, - &hr, - NULL); + &w2r); wh->cb = NULL; } TALER_EXCHANGE_withdraw2_cancel (wh); diff --git a/src/testing/testing_api_cmd_bank_history_credit.c b/src/testing/testing_api_cmd_bank_history_credit.c index 9a61d6d53..119c5d86c 100644 --- a/src/testing/testing_api_cmd_bank_history_credit.c +++ b/src/testing/testing_api_cmd_bank_history_credit.c @@ -386,10 +386,10 @@ history_cb (void *cls, GNUNET_break (0); goto error; case MHD_HTTP_OK: - for (unsigned int i = 0; idetails.success.details_length; i++) + for (unsigned int i = 0; idetails.ok.details_length; i++) { const struct TALER_BANK_CreditDetails *cd = - &chr->details.success.details[i]; + &chr->details.ok.details[i]; /* check current element */ if (GNUNET_OK != diff --git a/src/testing/testing_api_cmd_bank_history_debit.c b/src/testing/testing_api_cmd_bank_history_debit.c index 33b212ad0..fd1e81994 100644 --- a/src/testing/testing_api_cmd_bank_history_debit.c +++ b/src/testing/testing_api_cmd_bank_history_debit.c @@ -378,10 +378,10 @@ history_cb (void *cls, GNUNET_break (0); goto error; case MHD_HTTP_OK: - for (unsigned int i = 0; idetails.success.details_length; i++) + for (unsigned int i = 0; idetails.ok.details_length; i++) { const struct TALER_BANK_DebitDetails *dd = - &dhr->details.success.details[i]; + &dhr->details.ok.details[i]; /* check current element */ if (GNUNET_OK != diff --git a/src/testing/testing_api_cmd_batch_deposit.c b/src/testing/testing_api_cmd_batch_deposit.c index 54a20cdb2..d3275875d 100644 --- a/src/testing/testing_api_cmd_batch_deposit.c +++ b/src/testing/testing_api_cmd_batch_deposit.c @@ -212,17 +212,17 @@ batch_deposit_cb (void *cls, } if (MHD_HTTP_OK == dr->hr.http_status) { - if (ds->num_coins != dr->details.success.num_signatures) + if (ds->num_coins != dr->details.ok.num_signatures) { GNUNET_break (0); TALER_TESTING_interpreter_fail (ds->is); return; } ds->deposit_succeeded = GNUNET_YES; - ds->exchange_timestamp = dr->details.success.deposit_timestamp; - ds->exchange_pub = *dr->details.success.exchange_pub; - ds->exchange_sigs = GNUNET_memdup (dr->details.success.exchange_sigs, - dr->details.success.num_signatures + ds->exchange_timestamp = dr->details.ok.deposit_timestamp; + ds->exchange_pub = *dr->details.ok.exchange_pub; + ds->exchange_sigs = GNUNET_memdup (dr->details.ok.exchange_sigs, + dr->details.ok.num_signatures * sizeof (struct TALER_ExchangeSignatureP)); } diff --git a/src/testing/testing_api_cmd_batch_withdraw.c b/src/testing/testing_api_cmd_batch_withdraw.c index a5229ae9c..2aa549c0f 100644 --- a/src/testing/testing_api_cmd_batch_withdraw.c +++ b/src/testing/testing_api_cmd_batch_withdraw.c @@ -210,7 +210,7 @@ reserve_batch_withdraw_cb (void *cls, { struct CoinState *cs = &ws->coins[i]; const struct TALER_EXCHANGE_PrivateCoinDetails *pcd - = &wr->details.success.coins[i]; + = &wr->details.ok.coins[i]; TALER_denom_sig_deep_copy (&cs->sig, &pcd->sig); diff --git a/src/testing/testing_api_cmd_check_aml_decision.c b/src/testing/testing_api_cmd_check_aml_decision.c index d77e9b6b9..dd317142b 100644 --- a/src/testing/testing_api_cmd_check_aml_decision.c +++ b/src/testing/testing_api_cmd_check_aml_decision.c @@ -116,10 +116,10 @@ check_aml_decision_cb (void *cls, GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_amount (ref, &amount)); - for (unsigned int i = 0; idetails.success.aml_history_length; i++) + for (unsigned int i = 0; idetails.ok.aml_history_length; i++) { const struct TALER_EXCHANGE_AmlDecisionDetail *aml_history - = &adr->details.success.aml_history[i]; + = &adr->details.ok.aml_history[i]; if ( (NULL == oldest) || (0 != diff --git a/src/testing/testing_api_cmd_contract_get.c b/src/testing/testing_api_cmd_contract_get.c index 428bf7e8c..d599cb595 100644 --- a/src/testing/testing_api_cmd_contract_get.c +++ b/src/testing/testing_api_cmd_contract_get.c @@ -121,7 +121,7 @@ get_cb (void *cls, const struct TALER_PurseMergePrivateKeyP *mp; const json_t *ct; - ds->purse_pub = dr->details.success.purse_pub; + ds->purse_pub = dr->details.ok.purse_pub; if (ds->merge) { if (GNUNET_OK != @@ -136,8 +136,8 @@ get_cb (void *cls, TALER_CRYPTO_contract_decrypt_for_merge ( &ds->contract_priv, &ds->purse_pub, - dr->details.success.econtract, - dr->details.success.econtract_size, + dr->details.ok.econtract, + dr->details.ok.econtract_size, &ds->merge_priv); if (0 != GNUNET_memcmp (mp, @@ -153,8 +153,8 @@ get_cb (void *cls, ds->contract_terms = TALER_CRYPTO_contract_decrypt_for_deposit ( &ds->contract_priv, - dr->details.success.econtract, - dr->details.success.econtract_size); + dr->details.ok.econtract, + dr->details.ok.econtract_size); } if (NULL == ds->contract_terms) { diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 16ac139f4..1b097a346 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -264,9 +264,9 @@ deposit_cb (void *cls, if (MHD_HTTP_OK == dr->hr.http_status) { ds->deposit_succeeded = GNUNET_YES; - ds->exchange_timestamp = dr->details.success.deposit_timestamp; - ds->exchange_pub = *dr->details.success.exchange_pub; - ds->exchange_sig = *dr->details.success.exchange_sig; + ds->exchange_timestamp = dr->details.ok.deposit_timestamp; + ds->exchange_pub = *dr->details.ok.exchange_pub; + ds->exchange_sig = *dr->details.ok.exchange_sig; } TALER_TESTING_interpreter_next (ds->is); } diff --git a/src/testing/testing_api_cmd_deposits_get.c b/src/testing/testing_api_cmd_deposits_get.c index 8fd4e813c..8f7970895 100644 --- a/src/testing/testing_api_cmd_deposits_get.c +++ b/src/testing/testing_api_cmd_deposits_get.c @@ -128,7 +128,7 @@ deposit_wtid_cb (void *cls, switch (dr->hr.http_status) { case MHD_HTTP_OK: - tts->wtid = dr->details.success.wtid; + tts->wtid = dr->details.ok.wtid; if (NULL != tts->bank_transfer_reference) { const struct TALER_TESTING_Command *bank_transfer_cmd; @@ -155,7 +155,7 @@ deposit_wtid_cb (void *cls, } /* Compare that expected and gotten subjects match. */ - if (0 != GNUNET_memcmp (&dr->details.success.wtid, + if (0 != GNUNET_memcmp (&dr->details.ok.wtid, wtid_want)) { GNUNET_break (0); diff --git a/src/testing/testing_api_cmd_nexus_fetch_transactions.c b/src/testing/testing_api_cmd_nexus_fetch_transactions.c index 152647963..ff1497f3f 100644 --- a/src/testing/testing_api_cmd_nexus_fetch_transactions.c +++ b/src/testing/testing_api_cmd_nexus_fetch_transactions.c @@ -80,6 +80,7 @@ nft_run (void *cls, "wget", "--header=Content-Type:application/json", "--auth-no-challenge", + "--output-file=/dev/null", "--post-data={\"level\":\"all\",\"rangeType\":\"latest\"}", user, pass, diff --git a/src/testing/testing_api_cmd_purse_create_deposit.c b/src/testing/testing_api_cmd_purse_create_deposit.c index 200127b77..6fa7d91f9 100644 --- a/src/testing/testing_api_cmd_purse_create_deposit.c +++ b/src/testing/testing_api_cmd_purse_create_deposit.c @@ -176,8 +176,8 @@ deposit_cb (void *cls, } if (MHD_HTTP_OK == dr->hr.http_status) { - ds->exchange_pub = dr->details.success.exchange_pub; - ds->exchange_sig = dr->details.success.exchange_sig; + ds->exchange_pub = dr->details.ok.exchange_pub; + ds->exchange_sig = dr->details.ok.exchange_sig; } TALER_TESTING_interpreter_next (ds->is); } diff --git a/src/testing/testing_api_cmd_purse_deposit.c b/src/testing/testing_api_cmd_purse_deposit.c index ff8e6d2e3..aaf6ff6ba 100644 --- a/src/testing/testing_api_cmd_purse_deposit.c +++ b/src/testing/testing_api_cmd_purse_deposit.c @@ -152,8 +152,8 @@ deposit_cb (void *cls, if (MHD_HTTP_OK == dr->hr.http_status) { if (-1 != - TALER_amount_cmp (&dr->details.success.total_deposited, - &dr->details.success.purse_value_after_fees)) + TALER_amount_cmp (&dr->details.ok.total_deposited, + &dr->details.ok.purse_value_after_fees)) { const struct TALER_TESTING_Command *purse_cmd; const struct TALER_ReserveSignatureP *reserve_sig; @@ -213,7 +213,7 @@ deposit_cb (void *cls, /* Note: change when flags below changes! */ ds->reserve_history.amount - = dr->details.success.purse_value_after_fees; + = dr->details.ok.purse_value_after_fees; if (true) { ds->reserve_history.details.merge_details.purse_fee = gf->fees.purse; @@ -226,7 +226,7 @@ deposit_cb (void *cls, } } ds->reserve_history.details.merge_details.h_contract_terms - = dr->details.success.h_contract_terms; + = dr->details.ok.h_contract_terms; ds->reserve_history.details.merge_details.merge_pub = *merge_pub; ds->reserve_history.details.merge_details.purse_pub @@ -236,7 +236,7 @@ deposit_cb (void *cls, ds->reserve_history.details.merge_details.merge_timestamp = *merge_timestamp; ds->reserve_history.details.merge_details.purse_expiration - = dr->details.success.purse_expiration; + = dr->details.ok.purse_expiration; ds->reserve_history.details.merge_details.min_age = ds->min_age; ds->reserve_history.details.merge_details.flags diff --git a/src/testing/testing_api_cmd_purse_get.c b/src/testing/testing_api_cmd_purse_get.c index 3e7da38f0..60638752f 100644 --- a/src/testing/testing_api_cmd_purse_get.c +++ b/src/testing/testing_api_cmd_purse_get.c @@ -147,11 +147,11 @@ purse_status_cb (void *cls, TALER_string_to_amount (ss->expected_balance, &eb)); if (0 != TALER_amount_cmp (&eb, - &rs->details.success.balance)) + &rs->details.ok.balance)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected amount in purse: %s\n", - TALER_amount_to_string (&rs->details.success.balance)); + TALER_amount_to_string (&rs->details.ok.balance)); TALER_TESTING_interpreter_fail (ss->is); return; } diff --git a/src/testing/testing_api_cmd_recoup.c b/src/testing/testing_api_cmd_recoup.c index ed8c7eed7..e11475f20 100644 --- a/src/testing/testing_api_cmd_recoup.c +++ b/src/testing/testing_api_cmd_recoup.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -73,15 +73,14 @@ struct RecoupState * was paid back belonged to the right reserve. * * @param cls closure - * @param hr HTTP response details - * @param reserve_pub public key of the reserve receiving the recoup + * @param rr response details */ static void recoup_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ReservePublicKeyP *reserve_pub) + const struct TALER_EXCHANGE_RecoupResponse *rr) { struct RecoupState *ps = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr; struct TALER_TESTING_Interpreter *is = ps->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; const struct TALER_TESTING_Command *reserve_cmd; @@ -135,12 +134,6 @@ recoup_cb (void *cls, { const struct TALER_ReservePrivateKeyP *reserve_priv; - if (NULL == reserve_pub) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } if (GNUNET_OK != TALER_TESTING_get_trait_reserve_priv (reserve_cmd, &reserve_priv)) @@ -151,7 +144,7 @@ recoup_cb (void *cls, } GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv, &ps->reserve_pub.eddsa_pub); - if (0 != GNUNET_memcmp (reserve_pub, + if (0 != GNUNET_memcmp (&rr->details.ok.reserve_pub, &ps->reserve_pub)) { GNUNET_break (0); diff --git a/src/testing/testing_api_cmd_recoup_refresh.c b/src/testing/testing_api_cmd_recoup_refresh.c index 6081a4ba1..ff7dab004 100644 --- a/src/testing/testing_api_cmd_recoup_refresh.c +++ b/src/testing/testing_api_cmd_recoup_refresh.c @@ -73,15 +73,14 @@ struct RecoupRefreshState * was paid back belonged to the right old coin. * * @param cls closure - * @param hr HTTP response details - * @param old_coin_pub public key of the dirty coin + * @param rrr response details */ static void recoup_refresh_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_CoinSpendPublicKeyP *old_coin_pub) + const struct TALER_EXCHANGE_RecoupRefreshResponse *rrr) { struct RecoupRefreshState *rrs = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &rrr->hr; struct TALER_TESTING_Interpreter *is = rrs->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; char *cref; @@ -150,7 +149,7 @@ recoup_refresh_cb (void *cls, GNUNET_CRYPTO_eddsa_key_get_public (&dirty_priv->eddsa_priv, &oc.eddsa_pub); if (0 != GNUNET_memcmp (&oc, - old_coin_pub)) + &rrr->details.ok.old_coin_pub)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index 2aad77ce3..a8e2e8f39 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -411,7 +411,7 @@ reveal_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - rrs->num_fresh_coins = rr->details.success.num_coins; + rrs->num_fresh_coins = rr->details.ok.num_coins; rrs->psa = GNUNET_new_array (rrs->num_fresh_coins, struct TALER_PlanchetMasterSecretP); rrs->fresh_coins = GNUNET_new_array (rrs->num_fresh_coins, @@ -419,7 +419,7 @@ reveal_cb (void *cls, for (unsigned int i = 0; inum_fresh_coins; i++) { const struct TALER_EXCHANGE_RevealedCoinInfo *coin - = &rr->details.success.coins[i]; + = &rr->details.ok.coins[i]; struct TALER_TESTING_FreshCoinData *fc = &rrs->fresh_coins[i]; rrs->psa[i] = coin->ps; @@ -675,11 +675,11 @@ link_cb (void *cls, TALER_TESTING_interpreter_fail (rls->is); return; } - if (lr->details.success.num_coins != *num_fresh_coins) + if (lr->details.ok.num_coins != *num_fresh_coins) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected number of fresh coins: %d vs %d in %s:%u\n", - lr->details.success.num_coins, + lr->details.ok.num_coins, *num_fresh_coins, __FILE__, __LINE__); @@ -687,11 +687,11 @@ link_cb (void *cls, return; } /* check that the coins match */ - for (unsigned int i = 0; idetails.success.num_coins; i++) - for (unsigned int j = i + 1; jdetails.success.num_coins; j++) + for (unsigned int i = 0; idetails.ok.num_coins; i++) + for (unsigned int j = i + 1; jdetails.ok.num_coins; j++) if (0 == - GNUNET_memcmp (&lr->details.success.coins[i].coin_priv, - &lr->details.success.coins[j].coin_priv)) + GNUNET_memcmp (&lr->details.ok.coins[i].coin_priv, + &lr->details.ok.coins[j].coin_priv)) GNUNET_break (0); /* Note: coins might be legitimately permutated in here... */ found = 0; @@ -709,12 +709,12 @@ link_cb (void *cls, return; } - for (unsigned int i = 0; idetails.success.num_coins; i++) + for (unsigned int i = 0; idetails.ok.num_coins; i++) { const struct TALER_EXCHANGE_LinkedCoinInfo *lci_i - = &lr->details.success.coins[i]; + = &lr->details.ok.coins[i]; - for (unsigned int j = 0; jdetails.success.num_coins; j++) + for (unsigned int j = 0; jdetails.ok.num_coins; j++) { const struct TALER_TESTING_FreshCoinData *fcj = &(*fc)[j]; @@ -735,12 +735,12 @@ link_cb (void *cls, } /* for j*/ } /* for i */ } - if (found != lr->details.success.num_coins) + if (found != lr->details.ok.num_coins) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Only %u/%u coins match expectations\n", found, - lr->details.success.num_coins); + lr->details.ok.num_coins); GNUNET_break (0); TALER_TESTING_interpreter_fail (rls->is); return; @@ -952,16 +952,16 @@ melt_cb (void *cls, } if (MHD_HTTP_OK == hr->http_status) { - rms->noreveal_index = mr->details.success.noreveal_index; - if (mr->details.success.num_mbds != rms->num_fresh_coins) + rms->noreveal_index = mr->details.ok.noreveal_index; + if (mr->details.ok.num_mbds != rms->num_fresh_coins) { GNUNET_break (0); TALER_TESTING_interpreter_fail (rms->is); return; } GNUNET_free (rms->mbds); - rms->mbds = GNUNET_memdup (mr->details.success.mbds, - mr->details.success.num_mbds + rms->mbds = GNUNET_memdup (mr->details.ok.mbds, + mr->details.ok.num_mbds * sizeof (struct TALER_EXCHANGE_MeltBlindingDetail)); } diff --git a/src/testing/testing_api_cmd_refund.c b/src/testing/testing_api_cmd_refund.c index 4be3605a4..d41700d1a 100644 --- a/src/testing/testing_api_cmd_refund.c +++ b/src/testing/testing_api_cmd_refund.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2020 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -75,19 +75,14 @@ struct RefundState * response code is acceptable. * * @param cls closure - * @param hr HTTP response details - * @param exchange_pub public key the exchange - * used for signing @a obj. - * @param exchange_sig actual signature confirming the refund + * @param rr response details */ static void refund_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct TALER_ExchangeSignatureP *exchange_sig) + const struct TALER_EXCHANGE_RefundResponse *rr) { - struct RefundState *rs = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr; struct TALER_TESTING_Command *refund_cmd; refund_cmd = &rs->is->commands[rs->is->ip]; diff --git a/src/testing/testing_api_cmd_revoke_denom_key.c b/src/testing/testing_api_cmd_revoke_denom_key.c index 7c77c3566..8afd4f203 100644 --- a/src/testing/testing_api_cmd_revoke_denom_key.c +++ b/src/testing/testing_api_cmd_revoke_denom_key.c @@ -65,14 +65,15 @@ struct RevokeState * Function called with information about the post revocation operation result. * * @param cls closure with a `struct RevokeState *` - * @param hr HTTP response data + * @param rdr response data */ static void success_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *rdr) { struct RevokeState *rs = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &rdr->hr; rs->kh = NULL; if (rs->expected_response_code != hr->http_status) diff --git a/src/testing/testing_api_cmd_revoke_sign_key.c b/src/testing/testing_api_cmd_revoke_sign_key.c index 9745d728d..3b869312a 100644 --- a/src/testing/testing_api_cmd_revoke_sign_key.c +++ b/src/testing/testing_api_cmd_revoke_sign_key.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2020 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -65,14 +65,15 @@ struct RevokeState * Function called with information about the post revocation operation result. * * @param cls closure with a `struct RevokeState *` - * @param hr HTTP response data + * @param rsr response data */ static void success_cb ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *rsr) { struct RevokeState *rs = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &rsr->hr; rs->kh = NULL; if (rs->expected_response_code != hr->http_status) diff --git a/src/testing/testing_api_cmd_set_officer.c b/src/testing/testing_api_cmd_set_officer.c index 0e6de262f..1c0495f32 100644 --- a/src/testing/testing_api_cmd_set_officer.c +++ b/src/testing/testing_api_cmd_set_officer.c @@ -84,13 +84,15 @@ struct SetOfficerState * if the response code is acceptable. * * @param cls closure. - * @param hr HTTP response details + * @param ar response details */ static void set_officer_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct + TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *ar) { struct SetOfficerState *ds = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &ar->hr; ds->dh = NULL; if (MHD_HTTP_NO_CONTENT != hr->http_status) diff --git a/src/testing/testing_api_cmd_transfer_get.c b/src/testing/testing_api_cmd_transfer_get.c index 3c467e6da..cb6bb7dfa 100644 --- a/src/testing/testing_api_cmd_transfer_get.c +++ b/src/testing/testing_api_cmd_transfer_get.c @@ -115,15 +115,14 @@ track_transfer_cleanup (void *cls, * wire fees and hashed wire details as well. * * @param cls closure. - * @param hr HTTP response details - * @param ta transfer data returned by the exchange + * @param tgr response details */ static void track_transfer_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_TransferData *ta) + const struct TALER_EXCHANGE_TransfersGetResponse *tgr) { struct TrackTransferState *tts = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &tgr->hr; struct TALER_TESTING_Interpreter *is = tts->is; struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; struct TALER_Amount expected_amount; @@ -148,138 +147,62 @@ track_transfer_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - if (NULL == tts->expected_total_amount) { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - if (NULL == tts->expected_wire_fee) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } + const struct TALER_EXCHANGE_TransferData *ta + = &tgr->details.ok.td; - if (GNUNET_OK != - TALER_string_to_amount (tts->expected_total_amount, - &expected_amount)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - if (0 != TALER_amount_cmp (&ta->total_amount, - &expected_amount)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Total amount mismatch to command %s - " - "%s vs %s\n", - cmd->label, - TALER_amount_to_string (&ta->total_amount), - TALER_amount_to_string (&expected_amount)); - json_dumpf (hr->reply, - stderr, - 0); - fprintf (stderr, "\n"); - TALER_TESTING_interpreter_fail (is); - return; - } - - if (GNUNET_OK != - TALER_string_to_amount (tts->expected_wire_fee, - &expected_amount)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - - if (0 != TALER_amount_cmp (&ta->wire_fee, - &expected_amount)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Wire fee mismatch to command %s\n", - cmd->label); - json_dumpf (hr->reply, - stderr, - 0); - TALER_TESTING_interpreter_fail (is); - return; - } - - /** - * Optionally checking: (1) wire-details for this transfer - * match the ones from a referenced "deposit" operation - - * or any operation that could provide wire-details. (2) - * Total amount for this transfer matches the one from any - * referenced command that could provide one. - */ - if (NULL != tts->wire_details_reference) - { - const struct TALER_TESTING_Command *wire_details_cmd; - const char **payto_uri; - struct TALER_PaytoHashP h_payto; - - wire_details_cmd - = TALER_TESTING_interpreter_lookup_command (is, - tts->wire_details_reference); - if (NULL == wire_details_cmd) + if (NULL == tts->expected_total_amount) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); return; } + if (NULL == tts->expected_wire_fee) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != - TALER_TESTING_get_trait_payto_uri (wire_details_cmd, - &payto_uri)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - TALER_payto_hash (*payto_uri, - &h_payto); - if (0 != GNUNET_memcmp (&h_payto, - &ta->h_payto)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Wire hash missmath to command %s\n", - cmd->label); - json_dumpf (hr->reply, - stderr, - 0); - TALER_TESTING_interpreter_fail (is); - return; - } - } - if (NULL != tts->total_amount_reference) - { - const struct TALER_TESTING_Command *total_amount_cmd; - const struct TALER_Amount *total_amount_from_reference; - - total_amount_cmd - = TALER_TESTING_interpreter_lookup_command (is, - tts->total_amount_reference); - if (NULL == total_amount_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (total_amount_cmd, - &total_amount_from_reference)) + TALER_string_to_amount (tts->expected_total_amount, + &expected_amount)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); return; } if (0 != TALER_amount_cmp (&ta->total_amount, - total_amount_from_reference)) + &expected_amount)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Amount missmath to command %s\n", + "Total amount mismatch to command %s - " + "%s vs %s\n", + cmd->label, + TALER_amount_to_string (&ta->total_amount), + TALER_amount_to_string (&expected_amount)); + json_dumpf (hr->reply, + stderr, + 0); + fprintf (stderr, "\n"); + TALER_TESTING_interpreter_fail (is); + return; + } + + if (GNUNET_OK != + TALER_string_to_amount (tts->expected_wire_fee, + &expected_amount)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + + if (0 != TALER_amount_cmp (&ta->wire_fee, + &expected_amount)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Wire fee mismatch to command %s\n", cmd->label); json_dumpf (hr->reply, stderr, @@ -287,8 +210,92 @@ track_transfer_cb (void *cls, TALER_TESTING_interpreter_fail (is); return; } - } - } + + /** + * Optionally checking: (1) wire-details for this transfer + * match the ones from a referenced "deposit" operation - + * or any operation that could provide wire-details. (2) + * Total amount for this transfer matches the one from any + * referenced command that could provide one. + */ + if (NULL != tts->wire_details_reference) + { + const struct TALER_TESTING_Command *wire_details_cmd; + const char **payto_uri; + struct TALER_PaytoHashP h_payto; + + wire_details_cmd + = TALER_TESTING_interpreter_lookup_command (is, + tts-> + wire_details_reference); + if (NULL == wire_details_cmd) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_payto_uri (wire_details_cmd, + &payto_uri)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_payto_hash (*payto_uri, + &h_payto); + if (0 != GNUNET_memcmp (&h_payto, + &ta->h_payto)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Wire hash missmath to command %s\n", + cmd->label); + json_dumpf (hr->reply, + stderr, + 0); + TALER_TESTING_interpreter_fail (is); + return; + } + } + if (NULL != tts->total_amount_reference) + { + const struct TALER_TESTING_Command *total_amount_cmd; + const struct TALER_Amount *total_amount_from_reference; + + total_amount_cmd + = TALER_TESTING_interpreter_lookup_command (is, + tts-> + total_amount_reference); + if (NULL == total_amount_cmd) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_amount (total_amount_cmd, + &total_amount_from_reference)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (0 != TALER_amount_cmp (&ta->total_amount, + total_amount_from_reference)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Amount missmath to command %s\n", + cmd->label); + json_dumpf (hr->reply, + stderr, + 0); + TALER_TESTING_interpreter_fail (is); + return; + } + } + break; + } /* case OK */ + } /* switch on status */ TALER_TESTING_interpreter_next (is); } diff --git a/src/testing/testing_api_cmd_wire.c b/src/testing/testing_api_cmd_wire.c index 6e44403bc..5fbd41b1e 100644 --- a/src/testing/testing_api_cmd_wire.c +++ b/src/testing/testing_api_cmd_wire.c @@ -72,18 +72,14 @@ struct WireState * that the wire fee is acceptable too. * * @param cls closure. - * @param hr HTTP response details - * @param accounts_len length of the @a accounts array. - * @param accounts list of wire accounts of the exchange, - * NULL on error. + * @param wr response details */ static void wire_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - unsigned int accounts_len, - const struct TALER_EXCHANGE_WireAccount *accounts) + const struct TALER_EXCHANGE_WireResponse *wr) { struct WireState *ws = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &wr->hr; struct TALER_TESTING_Command *cmd = &ws->is->commands[ws->is->ip]; struct TALER_Amount expected_fee; @@ -100,6 +96,15 @@ wire_cb (void *cls, if (MHD_HTTP_OK == hr->http_status) { + unsigned int accounts_len + = wr->details.ok.accounts_len; + unsigned int fees_len + = wr->details.ok.fees_len; + const struct TALER_EXCHANGE_WireAccount *accounts + = wr->details.ok.accounts; + const struct TALER_EXCHANGE_WireFeesByMethod *fees + = wr->details.ok.fees; + for (unsigned int i = 0; imethod_found = GNUNET_OK; - if (NULL != ws->expected_fee) + } + GNUNET_free (method); + } + if (NULL != ws->expected_fee) + { + bool fee_found = false; + + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (ws->expected_fee, + &expected_fee)); + for (unsigned int i = 0; iexpected_method)) + continue; + for (const struct TALER_EXCHANGE_WireAggregateFees *waf + = fees[i].fees_head; + NULL != waf; + waf = waf->next) { - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (ws->expected_fee, - &expected_fee)); - for (const struct TALER_EXCHANGE_WireAggregateFees *waf - = accounts[i].fees; - NULL != waf; - waf = waf->next) + if (0 != TALER_amount_cmp (&waf->fees.wire, + &expected_fee)) { - if (0 != TALER_amount_cmp (&waf->fees.wire, - &expected_fee)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Wire fee mismatch to command %s\n", - cmd->label); - TALER_TESTING_interpreter_fail (ws->is); - GNUNET_free (method); - return; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Wire fee mismatch to command %s\n", + cmd->label); + TALER_TESTING_interpreter_fail (ws->is); + return; } + fee_found = true; } } - TALER_LOG_DEBUG ("Freeing method '%s'\n", - method); - GNUNET_free (method); + if (! fee_found) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "/wire does not contain expected fee '%s'\n", + ws->expected_fee); + TALER_TESTING_interpreter_fail (ws->is); + return; + } } if (GNUNET_OK != ws->method_found) { diff --git a/src/testing/testing_api_cmd_wire_add.c b/src/testing/testing_api_cmd_wire_add.c index c07e9bba6..c36f03b15 100644 --- a/src/testing/testing_api_cmd_wire_add.c +++ b/src/testing/testing_api_cmd_wire_add.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -67,13 +67,14 @@ struct WireAddState * if the response code is acceptable. * * @param cls closure. - * @param hr HTTP response details + * @param wer response details */ static void wire_add_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer) { struct WireAddState *ds = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &wer->hr; ds->dh = NULL; if (ds->expected_response_code != hr->http_status) @@ -110,10 +111,14 @@ wire_add_run (void *cls, struct TALER_MasterSignatureP master_sig1; struct TALER_MasterSignatureP master_sig2; struct GNUNET_TIME_Timestamp now; + json_t *credit_rest; + json_t *debit_rest; (void) cmd; now = GNUNET_TIME_timestamp_get (); ds->is = is; + debit_rest = json_array (); + credit_rest = json_array (); if (ds->bad_sig) { memset (&master_sig1, @@ -126,10 +131,16 @@ wire_add_run (void *cls, else { TALER_exchange_offline_wire_add_sign (ds->payto_uri, + NULL, + debit_rest, + credit_rest, now, &is->master_priv, &master_sig1); TALER_exchange_wire_signature_make (ds->payto_uri, + NULL, + debit_rest, + credit_rest, &is->master_priv, &master_sig2); } @@ -137,11 +148,16 @@ wire_add_run (void *cls, is->ctx, is->exchange_url, ds->payto_uri, + NULL, + debit_rest, + credit_rest, now, &master_sig1, &master_sig2, &wire_add_cb, ds); + json_decref (debit_rest); + json_decref (credit_rest); if (NULL == ds->dh) { GNUNET_break (0); diff --git a/src/testing/testing_api_cmd_wire_del.c b/src/testing/testing_api_cmd_wire_del.c index 15d29d727..89fb83957 100644 --- a/src/testing/testing_api_cmd_wire_del.c +++ b/src/testing/testing_api_cmd_wire_del.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020, 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -67,13 +67,14 @@ struct WireDelState * if the response code is acceptable. * * @param cls closure. - * @param hr HTTP response details + * @param wdr response details */ static void wire_del_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr) + const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdr) { struct WireDelState *ds = cls; + const struct TALER_EXCHANGE_HttpResponse *hr = &wdr->hr; ds->dh = NULL; if (ds->expected_response_code != hr->http_status) diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 1bd3c187e..8d53f4d07 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -297,10 +297,10 @@ reserve_withdraw_cb (void *cls, { case MHD_HTTP_OK: TALER_denom_sig_deep_copy (&ws->sig, - &wr->details.success.sig); - ws->coin_priv = wr->details.success.coin_priv; - ws->bks = wr->details.success.bks; - ws->exchange_vals = wr->details.success.exchange_vals; + &wr->details.ok.sig); + ws->coin_priv = wr->details.ok.coin_priv; + ws->bks = wr->details.ok.bks; + ws->exchange_vals = wr->details.ok.exchange_vals; if (0 != ws->total_backoff.rel_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index 1865a1129..3ac9bea20 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -526,49 +526,46 @@ sighandler_child_death (void) void TALER_TESTING_cert_cb (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_Keys *keys, - enum TALER_EXCHANGE_VersionCompatibility compat) + const struct TALER_EXCHANGE_KeysResponse *kr) { + const struct TALER_EXCHANGE_HttpResponse *hr = &kr->hr; struct MainContext *main_ctx = cls; struct TALER_TESTING_Interpreter *is = main_ctx->is; - (void) compat; - if (NULL == keys) + switch (hr->http_status) { - if (GNUNET_NO == is->working) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Got NULL response for /keys during startup (%u/%d), retrying!\n", - hr->http_status, - (int) hr->ec); - TALER_EXCHANGE_disconnect (is->exchange); - GNUNET_assert ( - NULL != (is->exchange - = TALER_EXCHANGE_connect (is->ctx, - main_ctx->exchange_url, - &TALER_TESTING_cert_cb, - main_ctx, - TALER_EXCHANGE_OPTION_END))); - return; - } - else + case MHD_HTTP_OK: + /* dealt with below */ + break; + default: + if (GNUNET_YES == is->working) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got NULL response for /keys during execution (%u/%d)!\n", hr->http_status, (int) hr->ec); + return; } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Got failure response for /keys during startup (%u/%d), retrying!\n", + hr->http_status, + (int) hr->ec); + TALER_EXCHANGE_disconnect (is->exchange); + GNUNET_assert ( + NULL != (is->exchange + = TALER_EXCHANGE_connect (is->ctx, + main_ctx->exchange_url, + &TALER_TESTING_cert_cb, + main_ctx, + TALER_EXCHANGE_OPTION_END))); + return; } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got %d DK from /keys in generation %u\n", - keys->num_denom_keys, - is->key_generation + 1); - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got %d DK from /keys in generation %u\n", + kr->details.ok.keys->num_denom_keys, + is->key_generation + 1); is->key_generation++; - is->keys = keys; + is->keys = kr->details.ok.keys; /* /keys has been called for some reason and * the interpreter is already running. */ diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c index b1e3b93a3..15dda8b34 100644 --- a/src/util/offline_signatures.c +++ b/src/util/offline_signatures.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2022 Taler Systems SA + Copyright (C) 2020-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -677,6 +677,22 @@ struct TALER_MasterAddWirePS * Hash over the exchange's payto URI. */ struct TALER_PaytoHashP h_payto GNUNET_PACKED; + + /** + * Hash over the conversion URL, all zeros if there + * is no conversion URL. + */ + struct GNUNET_HashCode h_conversion_url; + + /** + * Hash over the debit restrictions. + */ + struct GNUNET_HashCode h_debit_restrictions; + + /** + * Hash over the credit restrictions. + */ + struct GNUNET_HashCode h_credit_restrictions; }; GNUNET_NETWORK_STRUCT_END @@ -685,6 +701,9 @@ GNUNET_NETWORK_STRUCT_END void TALER_exchange_offline_wire_add_sign ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp now, const struct TALER_MasterPrivateKeyP *master_priv, struct TALER_MasterSignatureP *master_sig) @@ -697,6 +716,14 @@ TALER_exchange_offline_wire_add_sign ( TALER_payto_hash (payto_uri, &kv.h_payto); + if (NULL != conversion_url) + GNUNET_CRYPTO_hash (conversion_url, + strlen (conversion_url), + &kv.h_conversion_url); + TALER_json_hash (debit_restrictions, + &kv.h_debit_restrictions); + TALER_json_hash (credit_restrictions, + &kv.h_credit_restrictions); GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, &kv, &master_sig->eddsa_signature); @@ -706,6 +733,9 @@ TALER_exchange_offline_wire_add_sign ( enum GNUNET_GenericReturnValue TALER_exchange_offline_wire_add_verify ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp sign_time, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterSignatureP *master_sig) @@ -718,6 +748,14 @@ TALER_exchange_offline_wire_add_verify ( TALER_payto_hash (payto_uri, &aw.h_payto); + if (NULL != conversion_url) + GNUNET_CRYPTO_hash (conversion_url, + strlen (conversion_url), + &aw.h_conversion_url); + TALER_json_hash (debit_restrictions, + &aw.h_debit_restrictions); + TALER_json_hash (credit_restrictions, + &aw.h_credit_restrictions); return GNUNET_CRYPTO_eddsa_verify ( TALER_SIGNATURE_MASTER_ADD_WIRE, @@ -1095,6 +1133,22 @@ struct TALER_MasterWireDetailsPS */ struct TALER_PaytoHashP h_wire_details GNUNET_PACKED; + /** + * Hash over the conversion URL, all zeros if there + * is no conversion URL. + */ + struct GNUNET_HashCode h_conversion_url; + + /** + * Hash over the debit restrictions. + */ + struct GNUNET_HashCode h_debit_restrictions; + + /** + * Hash over the credit restrictions. + */ + struct GNUNET_HashCode h_credit_restrictions; + }; GNUNET_NETWORK_STRUCT_END @@ -1103,6 +1157,9 @@ GNUNET_NETWORK_STRUCT_END enum GNUNET_GenericReturnValue TALER_exchange_wire_signature_check ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterSignatureP *master_sig) { @@ -1113,6 +1170,14 @@ TALER_exchange_wire_signature_check ( TALER_payto_hash (payto_uri, &wd.h_wire_details); + if (NULL != conversion_url) + GNUNET_CRYPTO_hash (conversion_url, + strlen (conversion_url), + &wd.h_conversion_url); + TALER_json_hash (debit_restrictions, + &wd.h_debit_restrictions); + TALER_json_hash (credit_restrictions, + &wd.h_credit_restrictions); return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS, &wd, &master_sig->eddsa_signature, @@ -1123,6 +1188,9 @@ TALER_exchange_wire_signature_check ( void TALER_exchange_wire_signature_make ( const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, const struct TALER_MasterPrivateKeyP *master_priv, struct TALER_MasterSignatureP *master_sig) { @@ -1133,6 +1201,14 @@ TALER_exchange_wire_signature_make ( TALER_payto_hash (payto_uri, &wd.h_wire_details); + if (NULL != conversion_url) + GNUNET_CRYPTO_hash (conversion_url, + strlen (conversion_url), + &wd.h_conversion_url); + TALER_json_hash (debit_restrictions, + &wd.h_debit_restrictions); + TALER_json_hash (credit_restrictions, + &wd.h_credit_restrictions); GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, &wd, &master_sig->eddsa_signature);