From 332a37292c1db7261ebc6bb6fbb9ceacd7cc3220 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 6 Oct 2017 21:54:55 +0200 Subject: handle (most) TEH_KS_acquire errors --- src/exchange/taler-exchange-httpd_deposit.c | 19 +++++++++++++++++-- src/exchange/taler-exchange-httpd_keystate.c | 17 ++++++++++++++++- src/exchange/taler-exchange-httpd_keystate.h | 2 +- src/exchange/taler-exchange-httpd_payback.c | 7 +++++++ src/exchange/taler-exchange-httpd_refresh_melt.c | 21 ++++++++++++++------- src/exchange/taler-exchange-httpd_refresh_reveal.c | 12 +++++++++--- src/exchange/taler-exchange-httpd_refund.c | 16 +++++++++++++--- .../taler-exchange-httpd_reserve_withdraw.c | 8 ++++++++ 8 files changed, 85 insertions(+), 17 deletions(-) (limited to 'src/exchange') diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 8d824b7fd..ea77216f0 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -104,7 +104,7 @@ struct DepositContext * Value of the coin. */ struct TALER_Amount value; - + }; @@ -133,7 +133,7 @@ deposit_transaction (void *cls, struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_Amount spent; enum GNUNET_DB_QueryStatus qs; - + qs = TEH_plugin->have_deposit (TEH_plugin->cls, session, deposit); @@ -255,6 +255,13 @@ verify_and_execute_deposit (struct MHD_Connection *connection, /* check denomination */ mks = TEH_KS_acquire (); + if (NULL == mks) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } dki = TEH_KS_denomination_key_lookup (mks, &deposit->coin.denom_pub, TEH_KS_DKU_DEPOSIT); @@ -450,6 +457,14 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, /* check denomination exists and is valid */ key_state = TEH_KS_acquire (); + if (NULL == key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + GNUNET_JSON_parse_free (spec); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } dki = TEH_KS_denomination_key_lookup (key_state, &deposit.coin.denom_pub, TEH_KS_DKU_DEPOSIT); diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c index fc72a1305..033995c6a 100644 --- a/src/exchange/taler-exchange-httpd_keystate.c +++ b/src/exchange/taler-exchange-httpd_keystate.c @@ -1571,7 +1571,7 @@ TEH_KS_release_ (const char *location, * to #TEH_KS_release() must be made. * * @param location name of the function in which the lock is acquired - * @return the key state + * @return the key state, NULL on error (usually pretty fatal) */ struct TEH_KS_StateHandle * TEH_KS_acquire_ (const char *location) @@ -1837,6 +1837,11 @@ read_again: /** * Sign the message in @a purpose with the exchange's signing key. * + * FIXME: + * - Change API to return status code and do not assert on TEH_KS_acquire() + * failures, instead allow caller to handle it (i.e. by returning + * #TALER_EC_EXCHANGE_BAD_CONFIGURATION to application). + * * @param purpose the message to sign * @param[out] pub set to the current public signing key of the exchange * @param[out] sig signature over purpose using current signing key @@ -1850,6 +1855,9 @@ TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct TEH_KS_StateHandle *key_state; key_state = TEH_KS_acquire (); + GNUNET_assert (NULL != key_state); /* This *can* happen if the exchange's keys are + not properly maintained, but in this case we + simply have no good way forward. */ *pub = key_state->current_sign_key_issue.issue.signkey_pub; GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv.eddsa_priv, @@ -1930,6 +1938,13 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh, last_issue_date.abs_value_us = 0LLU; } key_state = TEH_KS_acquire (); + if (NULL == key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } krd = bsearch (&last_issue_date, key_state->krd_array, key_state->krd_array_length, diff --git a/src/exchange/taler-exchange-httpd_keystate.h b/src/exchange/taler-exchange-httpd_keystate.h index 2b7df6378..b2fb6f6d7 100644 --- a/src/exchange/taler-exchange-httpd_keystate.h +++ b/src/exchange/taler-exchange-httpd_keystate.h @@ -42,7 +42,7 @@ struct TEH_KS_StateHandle; * to #TEH_KS_release() must be made. * * @param location name of the function in which the lock is acquired - * @return the key state + * @return the key state, NULL on error (usually pretty fatal) */ struct TEH_KS_StateHandle * TEH_KS_acquire_ (const char *location); diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c index d8e1dd8ff..4e2e1e46a 100644 --- a/src/exchange/taler-exchange-httpd_payback.c +++ b/src/exchange/taler-exchange-httpd_payback.c @@ -312,6 +312,13 @@ verify_and_execute_payback (struct MHD_Connection *connection, /* check denomination exists and is in payback mode */ key_state = TEH_KS_acquire (); + if (NULL == key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } dki = TEH_KS_denomination_key_lookup (key_state, &coin->denom_pub, TEH_KS_DKU_PAYBACK); diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c index edcd84946..c9914f222 100644 --- a/src/exchange/taler-exchange-httpd_refresh_melt.c +++ b/src/exchange/taler-exchange-httpd_refresh_melt.c @@ -163,7 +163,7 @@ struct RefreshMeltContext /** * Information about the denomination key of the coin being * melted. - */ + */ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; /** @@ -184,7 +184,7 @@ struct RefreshMeltContext /** * Set to the session hash once the @e hash_context has finished. - */ + */ struct GNUNET_HashCode session_hash; /** @@ -220,7 +220,7 @@ struct RefreshMeltContext * @param[out] mhd_ret status code to return to MHD on hard error * @return transaction status code */ -static enum GNUNET_DB_QueryStatus +static enum GNUNET_DB_QueryStatus refresh_check_melt (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session, struct RefreshMeltContext *rmc, @@ -416,7 +416,7 @@ refresh_melt_prepare (struct MHD_Connection *connection, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "/refresh/melt request for session %s\n", GNUNET_h2s (&rmc->session_hash)); - + GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (TEH_exchange_currency_string, &total_cost)); @@ -700,7 +700,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, buf_size); GNUNET_free (buf); } - + /* decode JSON data on coin to melt and check that this is a valid coin */ { @@ -767,6 +767,13 @@ handle_refresh_melt_json (struct MHD_Connection *connection, rmc.hash_context = NULL; rmc.key_state = TEH_KS_acquire (); + if (NULL == rmc.key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } rmc.dki = TEH_KS_denomination_key_lookup (rmc.key_state, &rmc.coin_melt_details.coin_info.denom_pub, TEH_KS_DKU_DEPOSIT); @@ -804,7 +811,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT, "melt amount smaller than melting fee"); } - + if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, &body.purpose, @@ -818,7 +825,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, "confirm_sig"); } } - + /* prepare commit */ if (GNUNET_OK != refresh_melt_prepare (connection, diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c b/src/exchange/taler-exchange-httpd_refresh_reveal.c index cfb2b68ac..5d857fcae 100644 --- a/src/exchange/taler-exchange-httpd_refresh_reveal.c +++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c @@ -531,7 +531,7 @@ refresh_reveal_transaction (void *cls, for (unsigned int i=0;irefresh_session.noreveal_index) { off = 1; @@ -542,7 +542,7 @@ refresh_reveal_transaction (void *cls, rc->refresh_session.num_newcoins, rc->commit_coins); if (0 >= qs) - { + { cleanup_rc (rc); GNUNET_CRYPTO_hash_context_abort (hash_context); if (GNUNET_DB_STATUS_SOFT_ERROR == qs) @@ -596,7 +596,7 @@ refresh_reveal_transaction (void *cls, cleanup_rc (rc); return GNUNET_DB_STATUS_HARD_ERROR; } - + /* Client request OK, sign coins */ rc->ev_sigs = GNUNET_new_array (rc->refresh_session.num_newcoins, struct TALER_DenominationSignature); @@ -604,6 +604,12 @@ refresh_reveal_transaction (void *cls, struct TEH_KS_StateHandle *key_state; key_state = TEH_KS_acquire (); + if (NULL == key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + cleanup_rc (rc); + return GNUNET_DB_STATUS_HARD_ERROR; + } for (unsigned int j=0;jrefresh_session.num_newcoins;j++) { qs = refresh_exchange_coin (connection, diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index 9846c73ba..46c6dfd46 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -241,7 +241,7 @@ refund_transaction (void *cls, tl); *mhd_ret = TEH_RESPONSE_reply_transaction_unknown (connection, TALER_EC_REFUND_DEPOSIT_NOT_FOUND); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_DB_STATUS_HARD_ERROR; } /* handle if conflicting refund found */ if (GNUNET_SYSERR == refund_found) @@ -250,7 +250,7 @@ refund_transaction (void *cls, tl); TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); - return GNUNET_DB_STATUS_HARD_ERROR; + return GNUNET_DB_STATUS_HARD_ERROR; } /* handle if identical refund found */ if (GNUNET_YES == refund_found) @@ -297,7 +297,7 @@ refund_transaction (void *cls, } if (GNUNET_DB_STATUS_SOFT_ERROR == qs) return qs; /* go and retry */ - + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { /* money was already transferred to merchant, can no longer refund */ @@ -325,6 +325,16 @@ refund_transaction (void *cls, // FIXME: do this outside of transaction function? /* Check refund fee matches fee of denomination key! */ mks = TEH_KS_acquire (); + if (NULL == mks) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, + tl); + *mhd_ret = TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + return GNUNET_DB_STATUS_HARD_ERROR; + } dki = TEH_KS_denomination_key_lookup (mks, &dep->coin.denom_pub, TEH_KS_DKU_DEPOSIT); diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c index c410cea20..cc21972bc 100644 --- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c +++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c @@ -432,6 +432,14 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh, if (GNUNET_OK != res) return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; wc.key_state = TEH_KS_acquire (); + if (NULL == wc.key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + GNUNET_JSON_parse_free (spec); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } wc.dki = TEH_KS_denomination_key_lookup (wc.key_state, &wc.denomination_pub, TEH_KS_DKU_WITHDRAW); -- cgit v1.2.3