From e2deb89a3d070f6fa112009ce1e24652fd04ab2f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 6 Mar 2023 20:10:07 +0100 Subject: [PATCH 01/11] -fix missing /home/grothoff for taler-exchange-offline user --- debian/taler-exchange-offline.postinst | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/taler-exchange-offline.postinst b/debian/taler-exchange-offline.postinst index dfa755592..337bfa5d4 100644 --- a/debian/taler-exchange-offline.postinst +++ b/debian/taler-exchange-offline.postinst @@ -16,6 +16,7 @@ configure) --disabled-password \ --system \ --shell /bin/bash \ + --home /home/taler-exchange-offline \ --ingroup taler-exchange-offline \ taler-exchange-offline fi From 2d1583f96bdb3e02364beea59844af429bd84462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Mon, 6 Mar 2023 21:21:20 +0100 Subject: [PATCH 02/11] WiP: age-withdraw implementation, part 4/n - check dates of denominations (expiry, etc.) - refactor denomination checks into denomination_is_valid() --- ...taler-exchange-httpd_age-withdraw_reveal.c | 113 +++++++++++++----- 1 file changed, 86 insertions(+), 27 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c index daefca4c5..01e11fb4c 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c @@ -318,6 +318,87 @@ retrieve_original_commitment ( } +/** + * TODO + */ +static bool +denomination_is_valid ( + struct MHD_Connection *connection, + struct TEH_KeyStateHandle *ksh, + const struct TALER_DenominationHashP *denom_h, + struct TEH_DenominationKey *dks, + MHD_RESULT *result) +{ + dks = TEH_keys_denomination_by_hash2 ( + ksh, + denom_h, + connection, + result); + + /* Does the denomination exist? */ + if (NULL == dks) + { + GNUNET_assert (result != NULL); + /* Note: a HTTP-response has been queued and result has been set by + * TEH_keys_denominations_by_hash2 */ + return false; + } + + /* Is the denomation still and already valid? */ + + if (GNUNET_TIME_absolute_is_past (dks->meta.expire_withdraw.abs_time)) + { + /* This denomination is past the expiration time for withdraws */ + *result = TEH_RESPONSE_reply_expired_denom_pub_hash ( + connection, + denom_h, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, + "age-withdraw_reveal"); + return false; + } + + if (GNUNET_TIME_absolute_is_future (dks->meta.start.abs_time)) + { + /* This denomination is not yet valid */ + *result = TEH_RESPONSE_reply_expired_denom_pub_hash ( + connection, + denom_h, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, + "age-withdraw_reveal"); + return false; + } + + if (dks->recoup_possible) + { + /* This denomination has been revoked */ + *result = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_GONE, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, + NULL); + return false; + } + + /* Does the denomation support age restriction ? */ + if (0 == dks->denom_pub.age_mask.bits) + { + char msg[256] = {0}; + GNUNET_snprintf (msg, + sizeof(msg), + "denomination %s does not support age restriction", + GNUNET_h2s (&denom_h->hash)); + + *result = TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, + msg); + return GNUNET_SYSERR; + } + + return true; +} + + /** * Check if the given array of hashes of denomination_keys a) belong * to valid denominations and b) those are marked as age restricted. @@ -364,34 +445,12 @@ all_denominations_valid ( for (uint32_t i = 0; i < len; i++) { - dks[i] = TEH_keys_denomination_by_hash2 ( - ksh, - &denoms_h[i], - connection, - result); - - /* Does the denomination exist? */ - if (NULL == dks[i]) + if (! denomination_is_valid (connection, + ksh, + &denoms_h[i], + dks[i], + result)) { - GNUNET_assert (result != NULL); - /* Note: a HTTP-response has been queued and result has been set by - * TEH_keys_denominations_by_hash2 */ - return GNUNET_SYSERR; - } - - /* Does the denomation support age restriction ? */ - if (0 == dks[i]->denom_pub.age_mask.bits) - { - char msg[256] = {0}; - GNUNET_snprintf (msg, - sizeof(msg), - "denomination key no. %d does not support age restriction", - i + 1); - - *result = TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, - msg); return GNUNET_SYSERR; } From b7e20eb71e88e131335ac09d949b78020fb5b18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Mon, 6 Mar 2023 21:36:14 +0100 Subject: [PATCH 03/11] -minor refactoring in age_withdraw-reveal --- ...taler-exchange-httpd_age-withdraw_reveal.c | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c index 01e11fb4c..cdb8115f8 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c @@ -260,7 +260,7 @@ EXIT: /** * Check if the request belongs to an existing age-withdraw request. - * If so, sets the age_withdraw object with the request data. + * If so, sets the commitment object with the request data. * Otherwise, it queues an appropriate MHD response. * * @param connection The HTTP connection to the client @@ -272,7 +272,7 @@ EXIT: * GNUNET_SYSERROR if we did not find the request in the DB */ static enum GNUNET_GenericReturnValue -retrieve_original_commitment ( +find_original_commitment ( struct MHD_Connection *connection, const struct TALER_AgeWithdrawCommitmentHashP *h_commitment, const struct TALER_ReservePublicKeyP *reserve_pub, @@ -319,7 +319,15 @@ retrieve_original_commitment ( /** - * TODO + * Check if the given denomination is still or already valid, has not been + * revoked and supports age restriction. + * + * @param connection HTTP-connection to the client + * @param ksh The handle to the current state of (denomination) keys in the exchange + * @param denom_h Hash of the denomination key to check + * @param[out] dks On success, will contain the denomination key details + * @param[out] result On failure, an MHD-response will be qeued and result will be set to accordingly + * @return true on success (denomination valid), false otherwise */ static bool denomination_is_valid ( @@ -379,20 +387,21 @@ denomination_is_valid ( return false; } - /* Does the denomation support age restriction ? */ if (0 == dks->denom_pub.age_mask.bits) { + /* This denomation does not support age restriction */ char msg[256] = {0}; GNUNET_snprintf (msg, sizeof(msg), "denomination %s does not support age restriction", GNUNET_h2s (&denom_h->hash)); - *result = TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, - msg); - return GNUNET_SYSERR; + *result = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, + msg); + return false; } return true; @@ -415,7 +424,7 @@ denomination_is_valid ( * GNUNET_SYSERR otherwise */ static enum GNUNET_GenericReturnValue -all_denominations_valid ( +are_denominations_valid ( struct MHD_Connection *connection, uint32_t len, const struct TALER_DenominationHashP *denoms_h, @@ -544,24 +553,26 @@ TEH_handler_age_withdraw_reveal ( do { /* Extract denominations, blinded and disclosed coins */ - if (GNUNET_OK != parse_age_withdraw_reveal_json (rc->connection, - j_denoms_h, - j_coin_evs, - j_disclosed_coins, - &actx, - &result)) + if (GNUNET_OK != parse_age_withdraw_reveal_json ( + rc->connection, + j_denoms_h, + j_coin_evs, + j_disclosed_coins, + &actx, + &result)) break; /* Find original commitment */ - if (GNUNET_OK != retrieve_original_commitment (rc->connection, - &actx.ach, - &actx.reserve_pub, - &actx.commitment, - &result)) + if (GNUNET_OK != find_original_commitment ( + rc->connection, + &actx.ach, + &actx.reserve_pub, + &actx.commitment, + &result)) break; /* Ensure validity of denoms and the sum of amounts and fees */ - if (GNUNET_OK != all_denominations_valid ( + if (GNUNET_OK != are_denominations_valid ( rc->connection, actx.num_coins, actx.denoms_h, From 21c9dae382bb189a640e0e588eadfc80b1fb2563 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 8 Mar 2023 11:52:44 +0100 Subject: [PATCH 04/11] style fix --- src/exchange/taler-exchange-httpd_csr.c | 26 ++++++++---------------- src/exchange/taler-exchange-httpd_keys.c | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_csr.c b/src/exchange/taler-exchange-httpd_csr.c index a22fdfff5..29f83c2c9 100644 --- a/src/exchange/taler-exchange-httpd_csr.c +++ b/src/exchange/taler-exchange-httpd_csr.c @@ -234,12 +234,10 @@ TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, .cipher = TALER_DENOMINATION_CS }; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed ("nonce", - &nonce, - sizeof (struct TALER_CsNonce)), - GNUNET_JSON_spec_fixed ("denom_pub_hash", - &denom_pub_hash, - sizeof (struct TALER_DenominationHashP)), + GNUNET_JSON_spec_fixed_auto ("nonce", + &nonce), + GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", + &denom_pub_hash), GNUNET_JSON_spec_end () }; struct TEH_DenominationKey *dk; @@ -333,17 +331,11 @@ TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, } } - { - json_t *csr_obj; - - csr_obj = GNUNET_JSON_PACK ( - TALER_JSON_pack_exchange_withdraw_values ("ewv", - &ewv)); - GNUNET_assert (NULL != csr_obj); - return TALER_MHD_reply_json_steal (rc->connection, - csr_obj, - MHD_HTTP_OK); - } + return TALER_MHD_REPLY_JSON_PACK ( + rc->connection, + MHD_HTTP_OK, + TALER_JSON_pack_exchange_withdraw_values ("ewv", + &ewv)); } diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 8b72d7803..ce86e9515 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -738,7 +738,7 @@ free_denom_cb (void *cls, * @param value the `struct HelperSignkey` to release * @return #GNUNET_OK (continue to iterate) */ -static int +static enum GNUNET_GenericReturnValue free_esign_cb (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) From 890c9628177ee394d655e081361b2570db05827f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 8 Mar 2023 12:01:07 +0100 Subject: [PATCH 05/11] fix #7744 --- contrib/gana | 2 +- src/exchange/taler-exchange-httpd_keys.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/gana b/contrib/gana index 02132eded..1ec4596bf 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit 02132ededc12a0a1cfd81f0ca76c384304e15259 +Subproject commit 1ec4596bf4925ee24fc06d3e74d2a553b8239870 diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index ce86e9515..d73283509 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -3616,6 +3616,7 @@ TEH_keys_management_get_keys_handler (const struct TEH_RequestHandler *rh, if ( (GNUNET_is_zero (&denom_rsa_sm_pub)) && (GNUNET_is_zero (&denom_cs_sm_pub)) ) { + /* Either IPC failed, or neither helper had any denominations configured. */ return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_GATEWAY, TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE, @@ -3628,7 +3629,6 @@ TEH_keys_management_get_keys_handler (const struct TEH_RequestHandler *rh, TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE, NULL); } - // then a secmod helper is not yet running and we should return an MHD_HTTP_BAD_GATEWAY! GNUNET_assert (NULL != fbc.denoms); GNUNET_assert (NULL != fbc.signkeys); GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers->denom_keys, From 90664b555cd0b4cf4d4cba867100ca109aba057f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 8 Mar 2023 12:04:33 +0100 Subject: [PATCH 06/11] log URL in error message (fixes #7725) --- src/lib/exchange_api_reserves_get.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/exchange_api_reserves_get.c b/src/lib/exchange_api_reserves_get.c index d829b4593..1c2c2b027 100644 --- a/src/lib/exchange_api_reserves_get.c +++ b/src/lib/exchange_api_reserves_get.c @@ -168,9 +168,10 @@ handle_reserves_get_finished (void *cls, rs.hr.ec = TALER_JSON_get_error_code (j); rs.hr.hint = TALER_JSON_get_error_hint (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for reserves get\n", + "Unexpected response code %u/%d for GET %s\n", (unsigned int) response_code, - (int) rs.hr.ec); + (int) rs.hr.ec, + rgh->url); break; } if (NULL != rgh->cb) From 269425672cfb182e14ece6f383b42c3df1511a4c Mon Sep 17 00:00:00 2001 From: MS Date: Thu, 9 Mar 2023 18:02:28 +0100 Subject: [PATCH 07/11] typo --- contrib/gana | 2 +- src/exchange/taler-exchange-wirewatch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/gana b/contrib/gana index 1ec4596bf..02132eded 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit 1ec4596bf4925ee24fc06d3e74d2a553b8239870 +Subproject commit 02132ededc12a0a1cfd81f0ca76c384304e15259 diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c index a7a6b004f..168e7b9b7 100644 --- a/src/exchange/taler-exchange-wirewatch.c +++ b/src/exchange/taler-exchange-wirewatch.c @@ -757,7 +757,7 @@ continue_with_shard (void *cls) shard_end - latest_row_off); GNUNET_assert (NULL == hh); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Requesting credit history staring from %llu\n", + "Requesting credit history starting from %llu\n", (unsigned long long) latest_row_off); hh_start_time = GNUNET_TIME_absolute_get (); hh_returned_data = false; From 74facbead4d93a10248c6edf890fd8211e230229 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 9 Mar 2023 19:23:53 +0100 Subject: [PATCH 08/11] add comments --- src/bank-lib/bank_api_credit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c index 9835a8c9d..4842de969 100644 --- a/src/bank-lib/bank_api_credit.c +++ b/src/bank-lib/bank_api_credit.c @@ -248,12 +248,15 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx, { if ( (0 < num_results) && (! GNUNET_TIME_relative_is_zero (timeout)) ) + /* 0 == start_row is implied, go with timeout into future */ GNUNET_snprintf (url, sizeof (url), "history/incoming?delta=%lld&long_poll_ms=%llu", (long long) num_results, tms); else + /* Going back from current transaction or have no timeout; + hence timeout makes no sense */ GNUNET_snprintf (url, sizeof (url), "history/incoming?delta=%lld", @@ -263,6 +266,7 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx, { if ( (0 < num_results) && (! GNUNET_TIME_relative_is_zero (timeout)) ) + /* going forward from num_result */ GNUNET_snprintf (url, sizeof (url), "history/incoming?delta=%lld&start=%llu&long_poll_ms=%llu", @@ -270,6 +274,8 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx, (unsigned long long) start_row, tms); else + /* going backwards or have no timeout; + hence timeout makes no sense */ GNUNET_snprintf (url, sizeof (url), "history/incoming?delta=%lld&start=%llu", From 9d5549d6ba06d34597f00da21d19c6375a70f8aa Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 9 Mar 2023 19:48:29 +0100 Subject: [PATCH 09/11] retry on failure --- contrib/gana | 2 +- src/exchange/taler-exchange-httpd.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/contrib/gana b/contrib/gana index 02132eded..e2c325ca8 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit 02132ededc12a0a1cfd81f0ca76c384304e15259 +Subproject commit e2c325ca89b92aed98a30b23fd653b1adb9af683 diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index c88ddd7c8..d247d981b 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -80,6 +80,11 @@ */ #define UNIX_BACKLOG 50 +/** + * How often will we try to connect to the database before giving up? + */ +#define MAX_DB_RETRIES 5 + /** * Above what request latency do we start to log? */ @@ -1965,11 +1970,20 @@ exchange_serve_process_config (void) GNUNET_free (attr_enc_key_str); } - if (NULL == - (TEH_plugin = TALER_EXCHANGEDB_plugin_load (TEH_cfg))) + for (unsigned int i = 0; i Date: Fri, 10 Mar 2023 00:45:06 +0100 Subject: [PATCH 10/11] fix typo in comment --- debian/taler-exchange.taler-exchange-httpd.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/taler-exchange.taler-exchange-httpd.service b/debian/taler-exchange.taler-exchange-httpd.service index 98d76f6fb..ea78048e2 100644 --- a/debian/taler-exchange.taler-exchange-httpd.service +++ b/debian/taler-exchange.taler-exchange-httpd.service @@ -11,7 +11,7 @@ Type=simple # Depending on the configuration, the service suicides and then # needs to be restarted. Restart=always -# Do not dally on restarts. +# No significant delay on restarts. RestartSec=1ms ExecStart=/usr/bin/taler-exchange-httpd -c /etc/taler/taler.conf StandardOutput=journal From ce71db2c0b1a8dcc3021d2ba8549c31501c098b2 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 10 Mar 2023 12:18:56 +0100 Subject: [PATCH 11/11] be more explicit in systemd unit file --- contrib/gana | 2 +- debian/taler-exchange.taler-exchange-httpd.service | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/contrib/gana b/contrib/gana index e2c325ca8..1ec4596bf 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit e2c325ca89b92aed98a30b23fd653b1adb9af683 +Subproject commit 1ec4596bf4925ee24fc06d3e74d2a553b8239870 diff --git a/debian/taler-exchange.taler-exchange-httpd.service b/debian/taler-exchange.taler-exchange-httpd.service index ea78048e2..3671bdc7d 100644 --- a/debian/taler-exchange.taler-exchange-httpd.service +++ b/debian/taler-exchange.taler-exchange-httpd.service @@ -8,11 +8,19 @@ PartOf=taler-exchange.target [Service] User=taler-exchange-httpd Type=simple -# Depending on the configuration, the service suicides and then -# needs to be restarted. + +# Depending on the configuration, the service process kills itself and then +# needs to be restarted. Thus no significant delay on restarts. Restart=always -# No significant delay on restarts. RestartSec=1ms + +# Disable the service if more than 5 restarts are encountered within 5s. +# These are usually the systemd defaults, but can be overwritten, thus we set +# them here explicitly, as the exchange code assumes StartLimitInterval +# to be >=5s. +StartLimitBurst=5 +StartLimitInterval=5s + ExecStart=/usr/bin/taler-exchange-httpd -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal