From de9ab28ab9e55597baf2ca32194ec65b441f0f36 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 27 Feb 2020 23:46:53 +0100 Subject: rename fest, make symbols better match new endpoint names --- src/exchange/Makefile.am | 8 +- src/exchange/taler-exchange-httpd.c | 8 +- src/exchange/taler-exchange-httpd_deposits_get.c | 422 ++++++++++++++++ src/exchange/taler-exchange-httpd_deposits_get.h | 45 ++ src/exchange/taler-exchange-httpd_reserve_status.c | 175 ------- src/exchange/taler-exchange-httpd_reserve_status.h | 46 -- .../taler-exchange-httpd_reserve_withdraw.c | 509 ------------------- .../taler-exchange-httpd_reserve_withdraw.h | 51 -- src/exchange/taler-exchange-httpd_reserves_get.c | 175 +++++++ src/exchange/taler-exchange-httpd_reserves_get.h | 46 ++ .../taler-exchange-httpd_track_transaction.c | 422 ---------------- .../taler-exchange-httpd_track_transaction.h | 45 -- src/exchange/taler-exchange-httpd_track_transfer.c | 538 --------------------- src/exchange/taler-exchange-httpd_track_transfer.h | 43 -- src/exchange/taler-exchange-httpd_transfers_get.c | 538 +++++++++++++++++++++ src/exchange/taler-exchange-httpd_transfers_get.h | 43 ++ src/exchange/taler-exchange-httpd_withdraw.c | 509 +++++++++++++++++++ src/exchange/taler-exchange-httpd_withdraw.h | 51 ++ src/include/taler_exchange_service.h | 267 +++++----- src/lib/exchange_api_common.c | 14 +- src/lib/exchange_api_deposit.c | 4 +- src/lib/exchange_api_handle.c | 24 - src/lib/exchange_api_refund.c | 6 +- src/lib/exchange_api_reserve.c | 110 ++--- src/lib/exchange_api_track_transaction.c | 44 +- src/lib/exchange_api_track_transfer.c | 34 +- src/lib/exchange_api_wire.c | 4 +- .../testing_api_cmd_auditor_deposit_confirmation.c | 4 +- src/testing/testing_api_cmd_status.c | 12 +- src/testing/testing_api_cmd_track.c | 30 +- src/testing/testing_api_cmd_withdraw.c | 16 +- 31 files changed, 2103 insertions(+), 2140 deletions(-) create mode 100644 src/exchange/taler-exchange-httpd_deposits_get.c create mode 100644 src/exchange/taler-exchange-httpd_deposits_get.h delete mode 100644 src/exchange/taler-exchange-httpd_reserve_status.c delete mode 100644 src/exchange/taler-exchange-httpd_reserve_status.h delete mode 100644 src/exchange/taler-exchange-httpd_reserve_withdraw.c delete mode 100644 src/exchange/taler-exchange-httpd_reserve_withdraw.h create mode 100644 src/exchange/taler-exchange-httpd_reserves_get.c create mode 100644 src/exchange/taler-exchange-httpd_reserves_get.h delete mode 100644 src/exchange/taler-exchange-httpd_track_transaction.c delete mode 100644 src/exchange/taler-exchange-httpd_track_transaction.h delete mode 100644 src/exchange/taler-exchange-httpd_track_transfer.c delete mode 100644 src/exchange/taler-exchange-httpd_track_transfer.h create mode 100644 src/exchange/taler-exchange-httpd_transfers_get.c create mode 100644 src/exchange/taler-exchange-httpd_transfers_get.h create mode 100644 src/exchange/taler-exchange-httpd_withdraw.c create mode 100644 src/exchange/taler-exchange-httpd_withdraw.h diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index cf9f984de..fe1fd397f 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -49,6 +49,7 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd.c taler-exchange-httpd.h \ taler-exchange-httpd_db.c taler-exchange-httpd_db.h \ taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \ + taler-exchange-httpd_deposits_get.c taler-exchange-httpd_deposits_get.h \ taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \ taler-exchange-httpd_mhd.c taler-exchange-httpd_mhd.h \ taler-exchange-httpd_recoup.c taler-exchange-httpd_recoup.h \ @@ -56,13 +57,12 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_refresh_melt.c taler-exchange-httpd_refresh_melt.h \ taler-exchange-httpd_refresh_reveal.c taler-exchange-httpd_refresh_reveal.h \ taler-exchange-httpd_refund.c taler-exchange-httpd_refund.h \ - taler-exchange-httpd_reserve_status.c taler-exchange-httpd_reserve_status.h \ - taler-exchange-httpd_reserve_withdraw.c taler-exchange-httpd_reserve_withdraw.h \ + taler-exchange-httpd_reserves_get.c taler-exchange-httpd_reserves_get.h \ taler-exchange-httpd_responses.c taler-exchange-httpd_responses.h \ taler-exchange-httpd_terms.c taler-exchange-httpd_terms.h \ - taler-exchange-httpd_track_transaction.c taler-exchange-httpd_track_transaction.h \ - taler-exchange-httpd_track_transfer.c taler-exchange-httpd_track_transfer.h \ + taler-exchange-httpd_transfers_get.c taler-exchange-httpd_transfers_get.h \ taler-exchange-httpd_wire.c taler-exchange-httpd_wire.h \ + taler-exchange-httpd_withdraw.c taler-exchange-httpd_withdraw.h \ taler-exchange-httpd_validation.c taler-exchange-httpd_validation.h taler_exchange_httpd_LDADD = \ $(LIBGCRYPT_LIBS) \ diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index b2250fde2..8d5692967 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -30,15 +30,15 @@ #include "taler-exchange-httpd_mhd.h" #include "taler-exchange-httpd_deposit.h" #include "taler-exchange-httpd_refund.h" -#include "taler-exchange-httpd_reserve_status.h" -#include "taler-exchange-httpd_reserve_withdraw.h" +#include "taler-exchange-httpd_reserves_get.h" +#include "taler-exchange-httpd_withdraw.h" #include "taler-exchange-httpd_recoup.h" #include "taler-exchange-httpd_refresh_link.h" #include "taler-exchange-httpd_refresh_melt.h" #include "taler-exchange-httpd_refresh_reveal.h" #include "taler-exchange-httpd_terms.h" -#include "taler-exchange-httpd_track_transfer.h" -#include "taler-exchange-httpd_track_transaction.h" +#include "taler-exchange-httpd_transfers_get.h" +#include "taler-exchange-httpd_deposits_get.h" #include "taler-exchange-httpd_keystate.h" #include "taler-exchange-httpd_wire.h" #include "taler_exchangedb_plugin.h" diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c b/src/exchange/taler-exchange-httpd_deposits_get.c new file mode 100644 index 000000000..5e91bc4f3 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_deposits_get.c @@ -0,0 +1,422 @@ +/* + This file is part of TALER + Copyright (C) 2014-2017 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_deposits_get.c + * @brief Handle wire transfer tracking-related requests + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include +#include +#include +#include "taler_json_lib.h" +#include "taler_mhd_lib.h" +#include "taler_signatures.h" +#include "taler-exchange-httpd_keystate.h" +#include "taler-exchange-httpd_deposits_get.h" +#include "taler-exchange-httpd_responses.h" + + +/** + * A merchant asked for details about a deposit, but + * we did not execute the deposit yet. Generate a 202 reply. + * + * @param connection connection to the client + * @param planned_exec_time planned execution time + * @return MHD result code + */ +static int +reply_transfer_pending (struct MHD_Connection *connection, + struct GNUNET_TIME_Absolute planned_exec_time) +{ + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_ACCEPTED, + "{s:o}", + "execution_time", + GNUNET_JSON_from_time_abs ( + planned_exec_time)); +} + + +/** + * A merchant asked for details about a deposit. Provide + * them. Generates the 200 reply. + * + * @param connection connection to the client + * @param h_contract_terms hash of the contract + * @param h_wire hash of wire account details + * @param coin_pub public key of the coin + * @param coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value minus fee) + * @param wtid raw wire transfer identifier + * @param exec_time execution time of the wire transfer + * @return MHD result code + */ +static int +reply_track_transaction (struct MHD_Connection *connection, + const struct GNUNET_HashCode *h_contract_terms, + const struct GNUNET_HashCode *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *coin_contribution, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Absolute exec_time) +{ + struct TALER_ConfirmWirePS cw; + struct TALER_ExchangePublicKeyP pub; + struct TALER_ExchangeSignatureP sig; + + cw.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE); + cw.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS)); + cw.h_wire = *h_wire; + cw.h_contract_terms = *h_contract_terms; + cw.wtid = *wtid; + cw.coin_pub = *coin_pub; + cw.execution_time = GNUNET_TIME_absolute_hton (exec_time); + TALER_amount_hton (&cw.coin_contribution, + coin_contribution); + if (GNUNET_OK != + TEH_KS_sign (&cw.purpose, + &pub, + &sig)) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o, s:o, s:o}", + "wtid", GNUNET_JSON_from_data_auto ( + wtid), + "execution_time", + GNUNET_JSON_from_time_abs (exec_time), + "coin_contribution", + TALER_JSON_from_amount ( + coin_contribution), + "exchange_sig", + GNUNET_JSON_from_data_auto (&sig), + "exchange_pub", + GNUNET_JSON_from_data_auto (&pub)); +} + + +/** + * Closure for #handle_wtid_data. + */ +struct DepositWtidContext +{ + + /** + * Deposit details. + */ + const struct TALER_DepositTrackPS *tps; + + /** + * Public key of the merchant. + */ + const struct TALER_MerchantPublicKeyP *merchant_pub; + + /** + * Set by #handle_wtid data to the wire transfer ID. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * Set by #handle_wtid data to the coin's contribution to the wire transfer. + */ + struct TALER_Amount coin_contribution; + + /** + * Set by #handle_wtid data to the fee charged to the coin. + */ + struct TALER_Amount coin_fee; + + /** + * Set by #handle_wtid data to the wire transfer execution time. + */ + struct GNUNET_TIME_Absolute execution_time; + + /** + * Set by #handle_wtid to the coin contribution to the transaction + * (that is, @e coin_contribution minus @e coin_fee). + */ + struct TALER_Amount coin_delta; + + /** + * Set to #GNUNET_YES by #handle_wtid if the wire transfer is still pending + * (and the above were not set). + * Set to #GNUNET_SYSERR if there was a serious error. + */ + int pending; +}; + + +/** + * Function called with the results of the lookup of the + * wire transfer identifier information. + * + * @param cls our context for transmission + * @param wtid raw wire transfer identifier, NULL + * if the transaction was not yet done + * @param coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value including fee) + * @param coin_fee how much did the exchange charge for the deposit fee + * @param execution_time when was the transaction done, or + * when we expect it to be done (if @a wtid was NULL); + * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown + * to the exchange + */ +static void +handle_wtid_data (void *cls, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *coin_fee, + struct GNUNET_TIME_Absolute execution_time) +{ + struct DepositWtidContext *ctx = cls; + + if (NULL == wtid) + { + ctx->pending = GNUNET_YES; + ctx->execution_time = execution_time; + return; + } + if (GNUNET_SYSERR == + TALER_amount_subtract (&ctx->coin_delta, + coin_contribution, + coin_fee)) + { + GNUNET_break (0); + ctx->pending = GNUNET_SYSERR; + return; + } + ctx->wtid = *wtid; + ctx->execution_time = execution_time; + ctx->coin_contribution = *coin_contribution; + ctx->coin_fee = *coin_fee; +} + + +/** + * Execute a "/track/transaction". Returns the transfer information + * associated with the given deposit. + * + * If it returns a non-error code, the transaction logic MUST + * NOT queue a MHD response. IF it returns an hard error, the + * transaction logic MUST queue a MHD response and set @a mhd_ret. IF + * it returns the soft error code, the function MAY be called again to + * retry and MUST not queue a MHD response. + * + * @param cls closure of type `struct DepositWtidContext *` + * @param connection MHD request which triggered the transaction + * @param session database session to use + * @param[out] mhd_ret set to MHD response status for @a connection, + * if transaction failed (!) + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +track_transaction_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *mhd_ret) +{ + struct DepositWtidContext *ctx = cls; + enum GNUNET_DB_QueryStatus qs; + + qs = TEH_plugin->wire_lookup_deposit_wtid (TEH_plugin->cls, + session, + &ctx->tps->h_contract_terms, + &ctx->tps->h_wire, + &ctx->tps->coin_pub, + ctx->merchant_pub, + &handle_wtid_data, + ctx); + if (0 > qs) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED, + "failed to fetch transaction data"); + } + return qs; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_TRACK_TRANSACTION_NOT_FOUND, + "transaction unknown"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} + + +/** + * Check the merchant signature, and if it is valid, + * return the wire transfer identifier. + * + * @param connection the MHD connection to handle + * @param tps signed request to execute + * @param merchant_pub public key from the merchant + * @param merchant_sig signature from the merchant (to be checked) + * @return MHD result code + */ +static int +check_and_handle_track_transaction_request (struct MHD_Connection *connection, + const struct + TALER_DepositTrackPS *tps, + const struct + TALER_MerchantPublicKeyP * + merchant_pub, + const struct + TALER_MerchantSignatureP * + merchant_sig) +{ + struct DepositWtidContext ctx; + int mhd_ret; + + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION, + &tps->purpose, + &merchant_sig->eddsa_sig, + &merchant_pub->eddsa_pub)) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID, + "merchant_sig"); + } + ctx.pending = GNUNET_NO; + ctx.tps = tps; + ctx.merchant_pub = merchant_pub; + + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "handle track transaction", + &mhd_ret, + &track_transaction_transaction, + &ctx)) + return mhd_ret; + if (GNUNET_YES == ctx.pending) + return reply_transfer_pending (connection, + ctx.execution_time); + if (GNUNET_SYSERR == ctx.pending) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT, + "fees are inconsistent"); + return reply_track_transaction (connection, + &tps->h_contract_terms, + &tps->h_wire, + &tps->coin_pub, + &ctx.coin_delta, + &ctx.wtid, + ctx.execution_time); +} + + +/** + * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB" + * request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 4, contains: + * h_wire, merchant_pub, h_contract_terms and coin_pub) + * @return MHD result code + */ +int +TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[4]) +{ + int res; + struct TALER_DepositTrackPS tps; + struct TALER_MerchantSignatureP merchant_sig; + + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[0], + strlen (args[0]), + &tps.h_wire, + sizeof (tps.h_wire))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_DEPOSITS_INVALID_H_WIRE, + "wire hash malformed"); + } + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[1], + strlen (args[1]), + &tps.merchant, + sizeof (tps.merchant))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB, + "merchant public key malformed"); + } + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[2], + strlen (args[2]), + &tps.h_contract_terms, + sizeof (tps.h_contract_terms))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS, + "contract terms hash malformed"); + } + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[3], + strlen (args[3]), + &tps.coin_pub, + sizeof (tps.coin_pub))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_DEPOSITS_INVALID_COIN_PUB, + "coin public key malformed"); + } + res = TALER_MHD_parse_request_arg_data (connection, + "merchant_sig", + &merchant_sig, + sizeof (merchant_sig)); + if (GNUNET_SYSERR == res) + return MHD_NO; /* internal error */ + if (GNUNET_NO == res) + return MHD_YES; /* parse error */ + tps.purpose.size = htonl (sizeof (struct TALER_DepositTrackPS)); + tps.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION); + return check_and_handle_track_transaction_request (connection, + &tps, + &tps.merchant, + &merchant_sig); +} + + +/* end of taler-exchange-httpd_deposits_get.c */ diff --git a/src/exchange/taler-exchange-httpd_deposits_get.h b/src/exchange/taler-exchange-httpd_deposits_get.h new file mode 100644 index 000000000..27f57e679 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_deposits_get.h @@ -0,0 +1,45 @@ +/* + This file is part of TALER + Copyright (C) 2014-2017 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_deposits_get.h + * @brief Handle wire transfer tracking-related requests + * @author Christian Grothoff + */ +#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H +#define TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H + +#include +#include +#include "taler-exchange-httpd.h" + + +/** + * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB" + * request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 4, contains: + * h_wire, merchant_pub, h_contract_terms and coin_pub) + * @return MHD result code + */ +int +TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[4]); + + +#endif diff --git a/src/exchange/taler-exchange-httpd_reserve_status.c b/src/exchange/taler-exchange-httpd_reserve_status.c deleted file mode 100644 index 251271254..000000000 --- a/src/exchange/taler-exchange-httpd_reserve_status.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2020 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_reserve_status.c - * @brief Handle /reserves/$RESERVE_PUB GET requests - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include -#include "taler_mhd_lib.h" -#include "taler_json_lib.h" -#include "taler-exchange-httpd_reserve_status.h" -#include "taler-exchange-httpd_responses.h" -#include "taler-exchange-httpd_keystate.h" - - -/** - * Send reserve status information to client. - * - * @param connection connection to the client - * @param rh reserve history to return - * @return MHD result code - */ -static int -reply_reserve_status_success (struct MHD_Connection *connection, - const struct TALER_EXCHANGEDB_ReserveHistory *rh) -{ - json_t *json_balance; - json_t *json_history; - struct TALER_Amount balance; - - json_history = TEH_RESPONSE_compile_reserve_history (rh, - &balance); - if (NULL == json_history) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_RESERVE_STATUS_DB_ERROR, - "balance calculation failure"); - json_balance = TALER_JSON_from_amount (&balance); - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o, s:o}", - "balance", json_balance, - "history", json_history); -} - - -/** - * Closure for #reserve_status_transaction. - */ -struct ReserveStatusContext -{ - /** - * Public key of the reserve the inquiry is about. - */ - struct TALER_ReservePublicKeyP reserve_pub; - - /** - * History of the reserve, set in the callback. - */ - struct TALER_EXCHANGEDB_ReserveHistory *rh; - -}; - - -/** - * Function implementing /reserve/status transaction. - * Execute a /reserve/status. Given the public key of a reserve, - * return the associated transaction history. Runs the - * transaction logic; IF it returns a non-error code, the transaction - * logic MUST NOT queue a MHD response. IF it returns an hard error, - * the transaction logic MUST queue a MHD response and set @a mhd_ret. - * IF it returns the soft error code, the function MAY be called again - * to retry and MUST not queue a MHD response. - * - * @param cls a `struct ReserveStatusContext *` - * @param connection MHD request which triggered the transaction - * @param session database session to use - * @param[out] mhd_ret set to MHD response status for @a connection, - * if transaction failed (!); unused - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -reserve_status_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - int *mhd_ret) -{ - struct ReserveStatusContext *rsc = cls; - - (void) connection; - (void) mhd_ret; - return TEH_plugin->get_reserve_history (TEH_plugin->cls, - session, - &rsc->reserve_pub, - &rsc->rh); -} - - -/** - * Handle a GET "/reserves/" request. Parses the - * given "reserve_pub" in @a args (which should contain the - * EdDSA public key of a reserve) and then respond with the - * status of the reserve. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 1, just the reserve_pub) - * @return MHD result code - */ -int -TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[1]) -{ - struct ReserveStatusContext rsc; - int mhd_ret; - - (void) rh; - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[0], - strlen (args[0]), - &rsc.reserve_pub, - sizeof (rsc.reserve_pub))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_RESERVES_INVALID_RESERVE_PUB, - "reserve public key malformed"); - } - rsc.rh = NULL; - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "get reserve status", - &mhd_ret, - &reserve_status_transaction, - &rsc)) - return mhd_ret; - - /* generate proper response */ - if (NULL == rsc.rh) - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_NOT_FOUND, - "{s:s, s:s, s:I}", - "hint", "Reserve not found", - "parameter", "reserve_pub", - "code", - (json_int_t) - TALER_EC_RESERVE_STATUS_UNKNOWN); - mhd_ret = reply_reserve_status_success (connection, - rsc.rh); - TEH_plugin->free_reserve_history (TEH_plugin->cls, - rsc.rh); - return mhd_ret; -} - - -/* end of taler-exchange-httpd_reserve_status.c */ diff --git a/src/exchange/taler-exchange-httpd_reserve_status.h b/src/exchange/taler-exchange-httpd_reserve_status.h deleted file mode 100644 index 584bd3dcb..000000000 --- a/src/exchange/taler-exchange-httpd_reserve_status.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2020 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_reserve_status.h - * @brief Handle /reserves/$RESERVE_PUB GET requests - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#ifndef TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H -#define TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H - -#include -#include "taler-exchange-httpd.h" - - -/** - * Handle a GET "/reserves/" request. Parses the - * given "reserve_pub" in @a args (which should contain the - * EdDSA public key of a reserve) and then respond with the - * status of the reserve. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 1, just the reserve_pub) - * @return MHD result code - */ -int -TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[1]); - -#endif diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c deleted file mode 100644 index 25747eff0..000000000 --- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2019 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 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General - Public License along with TALER; see the file COPYING. If not, - see -*/ -/** - * @file taler-exchange-httpd_reserve_withdraw.c - * @brief Handle /reserve/withdraw requests - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-exchange-httpd_reserve_withdraw.h" -#include "taler-exchange-httpd_responses.h" -#include "taler-exchange-httpd_keystate.h" - - -/** - * Perform RSA signature before checking with the database? - * Reduces time spent in transaction, but may cause us to - * waste CPU time if DB check fails. - */ -#define OPTIMISTIC_SIGN 1 - - -/** - * Send reserve status information to client with the - * message that we have insufficient funds for the - * requested /reserve/withdraw operation. - * - * @param connection connection to the client - * @param rh reserve history to return - * @return MHD result code - */ -static int -reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection, - const struct - TALER_EXCHANGEDB_ReserveHistory *rh) -{ - json_t *json_balance; - json_t *json_history; - struct TALER_Amount balance; - - json_history = TEH_RESPONSE_compile_reserve_history (rh, - &balance); - if ((NULL == json_history) - /* Address the case where the ptr is not null, but - * it fails "internally" to dump as string (= corrupted). */ - || (0 == json_dumpb (json_history, NULL, 0, 0))) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS, - "balance calculation failure"); - json_balance = TALER_JSON_from_amount (&balance); - - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_CONFLICT, - "{s:s, s:I, s:o, s:o}", - "hint", "insufficient funds", - "code", - (json_int_t) - TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS, - "balance", json_balance, - "history", json_history); -} - - -/** - * Send blinded coin information to client. - * - * @param connection connection to the client - * @param collectable blinded coin to return - * @return MHD result code - */ -static int -reply_reserve_withdraw_success (struct MHD_Connection *connection, - const struct - TALER_EXCHANGEDB_CollectableBlindcoin * - collectable) -{ - json_t *sig_json; - - sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature); - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o}", - "ev_sig", sig_json); -} - - -/** - * Context for #withdraw_transaction. - */ -struct WithdrawContext -{ - /** - * Details about the withdrawal request. - */ - struct TALER_WithdrawRequestPS wsrd; - - /** - * Value of the coin plus withdraw fee. - */ - struct TALER_Amount amount_required; - - /** - * Hash of the denomination public key. - */ - struct GNUNET_HashCode denom_pub_hash; - - /** - * Signature over the request. - */ - struct TALER_ReserveSignatureP signature; - - /** - * Blinded planchet. - */ - char *blinded_msg; - - /** - * Key state to use to inspect previous withdrawal values. - */ - struct TEH_KS_StateHandle *key_state; - - /** - * Number of bytes in @e blinded_msg. - */ - size_t blinded_msg_len; - - /** - * Details about denomination we are about to withdraw. - */ - struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; - - /** - * Set to the resulting signed coin data to be returned to the client. - */ - struct TALER_EXCHANGEDB_CollectableBlindcoin collectable; - -}; - - -/** - * Function implementing /reserve/withdraw transaction. Runs the - * transaction logic; IF it returns a non-error code, the transaction - * logic MUST NOT queue a MHD response. IF it returns an hard error, - * the transaction logic MUST queue a MHD response and set @a mhd_ret. - * IF it returns the soft error code, the function MAY be called again - * to retry and MUST not queue a MHD response. - * - * Note that "wc->collectable.sig" may already be set before entering - * this function, either because OPTIMISTIC_SIGN was used and we signed - * before entering the transaction, or because this function is run - * twice (!) by #TEH_DB_run_transaction() and the first time created - * the signature and then failed to commit. Furthermore, we may get - * a 2nd correct signature briefly if "get_withdraw_info" suceeds and - * finds one in the DB. To avoid signing twice, the function may - * return a valid signature in "wc->collectable.sig" even if it failed. - * The caller must thus free the signature in either case. - * - * @param cls a `struct WithdrawContext *` - * @param connection MHD request which triggered the transaction - * @param session database session to use - * @param[out] mhd_ret set to MHD response status for @a connection, - * if transaction failed (!) - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -withdraw_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - int *mhd_ret) -{ - struct WithdrawContext *wc = cls; - struct TALER_EXCHANGEDB_Reserve r; - enum GNUNET_DB_QueryStatus qs; - struct TALER_Amount fee_withdraw; - struct TALER_DenominationSignature denom_sig; - -#if OPTIMISTIC_SIGN - /* store away optimistic signature to protect - it from being overwritten by get_withdraw_info */ - denom_sig = wc->collectable.sig; - wc->collectable.sig.rsa_signature = NULL; -#endif - qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls, - session, - &wc->wsrd.h_coin_envelope, - &wc->collectable); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_DB_FETCH_ERROR, - "failed to fetch withdraw data"); - wc->collectable.sig = denom_sig; - return qs; - } - - /* Don't sign again if we have already signed the coin */ - if (1 == qs) - { -#if OPTIMISTIC_SIGN - GNUNET_CRYPTO_rsa_signature_free (denom_sig.rsa_signature); -#endif - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - } - GNUNET_assert (0 == qs); - wc->collectable.sig = denom_sig; - - /* Check if balance is sufficient */ - r.pub = wc->wsrd.reserve_pub; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Trying to withdraw from reserve: %s\n", - TALER_B2S (&r.pub)); - qs = TEH_plugin->reserve_get (TEH_plugin->cls, - session, - &r); - if (0 > qs) - { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_DB_FETCH_ERROR, - "failed to fetch reserve data"); - return qs; - } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_WITHDRAW_RESERVE_UNKNOWN, - "reserve_pub"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - if (0 < TALER_amount_cmp (&wc->amount_required, - &r.balance)) - { - char *amount_required; - char *r_balance; - struct TALER_EXCHANGEDB_ReserveHistory *rh; - /* The reserve does not have the required amount (actual - * amount + withdraw fee) */ - GNUNET_break_op (0); - amount_required = TALER_amount_to_string (&wc->amount_required); - r_balance = TALER_amount_to_string (&r.balance); - TALER_LOG_WARNING ("Asked %s over a reserve worth %s\n", - amount_required, - r_balance); - GNUNET_free (amount_required); - GNUNET_free (r_balance); - qs = TEH_plugin->get_reserve_history (TEH_plugin->cls, - session, - &wc->wsrd.reserve_pub, - &rh); - if (NULL == rh) - { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_DB_FETCH_ERROR, - "failed to fetch reserve history"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - *mhd_ret = reply_reserve_withdraw_insufficient_funds (connection, - rh); - TEH_plugin->free_reserve_history (TEH_plugin->cls, - rh); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - /* Balance is good, sign the coin! */ -#if ! OPTIMISTIC_SIGN - if (NULL == wc->collectable.sig.rsa_signature) - { - wc->collectable.sig.rsa_signature - = GNUNET_CRYPTO_rsa_sign_blinded (wc->dki->denom_priv.rsa_private_key, - wc->blinded_msg, - wc->blinded_msg_len); - if (NULL == wc->collectable.sig.rsa_signature) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_SIGNATURE_FAILED, - "Failed to create signature"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - } -#endif - TALER_amount_ntoh (&fee_withdraw, - &wc->dki->issue.properties.fee_withdraw); - wc->collectable.denom_pub_hash = wc->denom_pub_hash; - wc->collectable.amount_with_fee = wc->amount_required; - wc->collectable.withdraw_fee = fee_withdraw; - wc->collectable.reserve_pub = wc->wsrd.reserve_pub; - wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope; - wc->collectable.reserve_sig = wc->signature; - qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls, - session, - &wc->collectable); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_DB_STORE_ERROR, - "failed to persist withdraw data"); - return qs; - } - return qs; -} - - -/** - * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the - * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which - * specifies the key/value of the coin to be withdrawn, and checks that the - * signature "reserve_sig" makes this a valid withdrawal request from the - * specified reserve. If so, the envelope with the blinded coin "coin_ev" is - * passed down to execute the withdrawl operation. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param root uploaded JSON data - * @param args array of additional options (first must be the - * reserve public key, the second one should be "withdraw") - * @return MHD result code - */ -int -TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const json_t *root, - const char *const args[2]) -{ - struct WithdrawContext wc; - int res; - int mhd_ret; - unsigned int hc; - enum TALER_ErrorCode ec; - struct TALER_Amount amount; - struct TALER_Amount fee_withdraw; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_varsize ("coin_ev", - (void **) &wc.blinded_msg, - &wc.blinded_msg_len), - GNUNET_JSON_spec_fixed_auto ("reserve_sig", - &wc.signature), - GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", - &wc.denom_pub_hash), - GNUNET_JSON_spec_end () - }; - - (void) rh; - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[0], - strlen (args[0]), - &wc.wsrd.reserve_pub, - sizeof (wc.wsrd.reserve_pub))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_RESERVES_INVALID_RESERVE_PUB, - "reserve public key malformed"); - } - - res = TALER_MHD_parse_json_data (connection, - root, - spec); - if (GNUNET_OK != res) - return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - wc.key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); - if (NULL == wc.key_state) - { - TALER_LOG_ERROR ("Lacking keys to operate\n"); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_BAD_CONFIGURATION, - "no keys"); - } - wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state, - &wc.denom_pub_hash, - TEH_KS_DKU_WITHDRAW, - &ec, - &hc); - if (NULL == wc.dki) - { - GNUNET_JSON_parse_free (spec); - TEH_KS_release (wc.key_state); - return TALER_MHD_reply_with_error (connection, - hc, - ec, - "could not find denomination key"); - } - GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key); - TALER_amount_ntoh (&amount, - &wc.dki->issue.properties.value); - TALER_amount_ntoh (&fee_withdraw, - &wc.dki->issue.properties.fee_withdraw); - if (GNUNET_OK != - TALER_amount_add (&wc.amount_required, - &amount, - &fee_withdraw)) - { - GNUNET_JSON_parse_free (spec); - TEH_KS_release (wc.key_state); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW, - "amount overflow for value plus withdraw fee"); - } - TALER_amount_hton (&wc.wsrd.amount_with_fee, - &wc.amount_required); - TALER_amount_hton (&wc.wsrd.withdraw_fee, - &fee_withdraw); - /* verify signature! */ - wc.wsrd.purpose.size - = htonl (sizeof (struct TALER_WithdrawRequestPS)); - wc.wsrd.purpose.purpose - = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); - wc.wsrd.h_denomination_pub - = wc.denom_pub_hash; - GNUNET_CRYPTO_hash (wc.blinded_msg, - wc.blinded_msg_len, - &wc.wsrd.h_coin_envelope); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW, - &wc.wsrd.purpose, - &wc.signature.eddsa_signature, - &wc.wsrd.reserve_pub.eddsa_pub)) - { - TALER_LOG_WARNING ( - "Client supplied invalid signature for /reserve/withdraw request\n"); - GNUNET_JSON_parse_free (spec); - TEH_KS_release (wc.key_state); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID, - "reserve_sig"); - } - -#if OPTIMISTIC_SIGN - /* Sign before transaction! */ - wc.collectable.sig.rsa_signature - = GNUNET_CRYPTO_rsa_sign_blinded (wc.dki->denom_priv.rsa_private_key, - wc.blinded_msg, - wc.blinded_msg_len); - if (NULL == wc.collectable.sig.rsa_signature) - { - GNUNET_break (0); - GNUNET_JSON_parse_free (spec); - TEH_KS_release (wc.key_state); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_WITHDRAW_SIGNATURE_FAILED, - "Failed to sign"); - } -#endif - - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "run reserve withdraw", - &mhd_ret, - &withdraw_transaction, - &wc)) - { - TEH_KS_release (wc.key_state); - /* Even if #withdraw_transaction() failed, it may have created a signature - (or we might have done it optimistically above). */ - if (NULL != wc.collectable.sig.rsa_signature) - GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature); - GNUNET_JSON_parse_free (spec); - return mhd_ret; - } - TEH_KS_release (wc.key_state); - GNUNET_JSON_parse_free (spec); - - mhd_ret = reply_reserve_withdraw_success (connection, - &wc.collectable); - GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature); - return mhd_ret; -} - - -/* end of taler-exchange-httpd_reserve_withdraw.c */ diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.h b/src/exchange/taler-exchange-httpd_reserve_withdraw.h deleted file mode 100644 index c3e56eaaf..000000000 --- a/src/exchange/taler-exchange-httpd_reserve_withdraw.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2020 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_reserve_withdraw.h - * @brief Handle /reserve/withdraw requests - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#ifndef TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H -#define TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H - -#include -#include "taler-exchange-httpd.h" - - -/** - * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the - * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which - * specifies the key/value of the coin to be withdrawn, and checks that the - * signature "reserve_sig" makes this a valid withdrawl request from the - * specified reserve. If so, the envelope with the blinded coin "coin_ev" is - * passed down to execute the withdrawl operation. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param root uploaded JSON data - * @param args array of additional options (first must be the - * reserve public key, the second one should be "withdraw") - * @return MHD result code - */ -int -TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const json_t *root, - const char *const args[2]); - -#endif diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c b/src/exchange/taler-exchange-httpd_reserves_get.c new file mode 100644 index 000000000..d06a871e7 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_reserves_get.c @@ -0,0 +1,175 @@ +/* + This file is part of TALER + Copyright (C) 2014-2020 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_reserves_get.c + * @brief Handle /reserves/$RESERVE_PUB GET requests + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include +#include "taler_mhd_lib.h" +#include "taler_json_lib.h" +#include "taler-exchange-httpd_reserves_get.h" +#include "taler-exchange-httpd_responses.h" +#include "taler-exchange-httpd_keystate.h" + + +/** + * Send reserve status information to client. + * + * @param connection connection to the client + * @param rh reserve history to return + * @return MHD result code + */ +static int +reply_reserve_status_success (struct MHD_Connection *connection, + const struct TALER_EXCHANGEDB_ReserveHistory *rh) +{ + json_t *json_balance; + json_t *json_history; + struct TALER_Amount balance; + + json_history = TEH_RESPONSE_compile_reserve_history (rh, + &balance); + if (NULL == json_history) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_RESERVE_STATUS_DB_ERROR, + "balance calculation failure"); + json_balance = TALER_JSON_from_amount (&balance); + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o}", + "balance", json_balance, + "history", json_history); +} + + +/** + * Closure for #reserve_status_transaction. + */ +struct ReserveStatusContext +{ + /** + * Public key of the reserve the inquiry is about. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * History of the reserve, set in the callback. + */ + struct TALER_EXCHANGEDB_ReserveHistory *rh; + +}; + + +/** + * Function implementing /reserve/status transaction. + * Execute a /reserve/status. Given the public key of a reserve, + * return the associated transaction history. Runs the + * transaction logic; IF it returns a non-error code, the transaction + * logic MUST NOT queue a MHD response. IF it returns an hard error, + * the transaction logic MUST queue a MHD response and set @a mhd_ret. + * IF it returns the soft error code, the function MAY be called again + * to retry and MUST not queue a MHD response. + * + * @param cls a `struct ReserveStatusContext *` + * @param connection MHD request which triggered the transaction + * @param session database session to use + * @param[out] mhd_ret set to MHD response status for @a connection, + * if transaction failed (!); unused + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +reserve_status_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *mhd_ret) +{ + struct ReserveStatusContext *rsc = cls; + + (void) connection; + (void) mhd_ret; + return TEH_plugin->get_reserve_history (TEH_plugin->cls, + session, + &rsc->reserve_pub, + &rsc->rh); +} + + +/** + * Handle a GET "/reserves/" request. Parses the + * given "reserve_pub" in @a args (which should contain the + * EdDSA public key of a reserve) and then respond with the + * status of the reserve. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 1, just the reserve_pub) + * @return MHD result code + */ +int +TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[1]) +{ + struct ReserveStatusContext rsc; + int mhd_ret; + + (void) rh; + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[0], + strlen (args[0]), + &rsc.reserve_pub, + sizeof (rsc.reserve_pub))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_RESERVES_INVALID_RESERVE_PUB, + "reserve public key malformed"); + } + rsc.rh = NULL; + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "get reserve status", + &mhd_ret, + &reserve_status_transaction, + &rsc)) + return mhd_ret; + + /* generate proper response */ + if (NULL == rsc.rh) + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_NOT_FOUND, + "{s:s, s:s, s:I}", + "hint", "Reserve not found", + "parameter", "reserve_pub", + "code", + (json_int_t) + TALER_EC_RESERVE_STATUS_UNKNOWN); + mhd_ret = reply_reserve_status_success (connection, + rsc.rh); + TEH_plugin->free_reserve_history (TEH_plugin->cls, + rsc.rh); + return mhd_ret; +} + + +/* end of taler-exchange-httpd_reserves_get.c */ diff --git a/src/exchange/taler-exchange-httpd_reserves_get.h b/src/exchange/taler-exchange-httpd_reserves_get.h new file mode 100644 index 000000000..bc697dcd4 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_reserves_get.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2014-2020 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_reserves_get.h + * @brief Handle /reserves/$RESERVE_PUB GET requests + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#ifndef TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H +#define TALER_EXCHANGE_HTTPD_RESERVE_STATUS_H + +#include +#include "taler-exchange-httpd.h" + + +/** + * Handle a GET "/reserves/" request. Parses the + * given "reserve_pub" in @a args (which should contain the + * EdDSA public key of a reserve) and then respond with the + * status of the reserve. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 1, just the reserve_pub) + * @return MHD result code + */ +int +TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[1]); + +#endif diff --git a/src/exchange/taler-exchange-httpd_track_transaction.c b/src/exchange/taler-exchange-httpd_track_transaction.c deleted file mode 100644 index d0f1d0aa3..000000000 --- a/src/exchange/taler-exchange-httpd_track_transaction.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2017 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_track_transaction.c - * @brief Handle wire transfer tracking-related requests - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include -#include -#include -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler_signatures.h" -#include "taler-exchange-httpd_keystate.h" -#include "taler-exchange-httpd_track_transaction.h" -#include "taler-exchange-httpd_responses.h" - - -/** - * A merchant asked for details about a deposit, but - * we did not execute the deposit yet. Generate a 202 reply. - * - * @param connection connection to the client - * @param planned_exec_time planned execution time - * @return MHD result code - */ -static int -reply_transfer_pending (struct MHD_Connection *connection, - struct GNUNET_TIME_Absolute planned_exec_time) -{ - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_ACCEPTED, - "{s:o}", - "execution_time", - GNUNET_JSON_from_time_abs ( - planned_exec_time)); -} - - -/** - * A merchant asked for details about a deposit. Provide - * them. Generates the 200 reply. - * - * @param connection connection to the client - * @param h_contract_terms hash of the contract - * @param h_wire hash of wire account details - * @param coin_pub public key of the coin - * @param coin_contribution how much did the coin we asked about - * contribute to the total transfer value? (deposit value minus fee) - * @param wtid raw wire transfer identifier - * @param exec_time execution time of the wire transfer - * @return MHD result code - */ -static int -reply_track_transaction (struct MHD_Connection *connection, - const struct GNUNET_HashCode *h_contract_terms, - const struct GNUNET_HashCode *h_wire, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *coin_contribution, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct GNUNET_TIME_Absolute exec_time) -{ - struct TALER_ConfirmWirePS cw; - struct TALER_ExchangePublicKeyP pub; - struct TALER_ExchangeSignatureP sig; - - cw.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE); - cw.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS)); - cw.h_wire = *h_wire; - cw.h_contract_terms = *h_contract_terms; - cw.wtid = *wtid; - cw.coin_pub = *coin_pub; - cw.execution_time = GNUNET_TIME_absolute_hton (exec_time); - TALER_amount_hton (&cw.coin_contribution, - coin_contribution); - if (GNUNET_OK != - TEH_KS_sign (&cw.purpose, - &pub, - &sig)) - { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_BAD_CONFIGURATION, - "no keys"); - } - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o, s:o, s:o, s:o, s:o}", - "wtid", GNUNET_JSON_from_data_auto ( - wtid), - "execution_time", - GNUNET_JSON_from_time_abs (exec_time), - "coin_contribution", - TALER_JSON_from_amount ( - coin_contribution), - "exchange_sig", - GNUNET_JSON_from_data_auto (&sig), - "exchange_pub", - GNUNET_JSON_from_data_auto (&pub)); -} - - -/** - * Closure for #handle_wtid_data. - */ -struct DepositWtidContext -{ - - /** - * Deposit details. - */ - const struct TALER_DepositTrackPS *tps; - - /** - * Public key of the merchant. - */ - const struct TALER_MerchantPublicKeyP *merchant_pub; - - /** - * Set by #handle_wtid data to the wire transfer ID. - */ - struct TALER_WireTransferIdentifierRawP wtid; - - /** - * Set by #handle_wtid data to the coin's contribution to the wire transfer. - */ - struct TALER_Amount coin_contribution; - - /** - * Set by #handle_wtid data to the fee charged to the coin. - */ - struct TALER_Amount coin_fee; - - /** - * Set by #handle_wtid data to the wire transfer execution time. - */ - struct GNUNET_TIME_Absolute execution_time; - - /** - * Set by #handle_wtid to the coin contribution to the transaction - * (that is, @e coin_contribution minus @e coin_fee). - */ - struct TALER_Amount coin_delta; - - /** - * Set to #GNUNET_YES by #handle_wtid if the wire transfer is still pending - * (and the above were not set). - * Set to #GNUNET_SYSERR if there was a serious error. - */ - int pending; -}; - - -/** - * Function called with the results of the lookup of the - * wire transfer identifier information. - * - * @param cls our context for transmission - * @param wtid raw wire transfer identifier, NULL - * if the transaction was not yet done - * @param coin_contribution how much did the coin we asked about - * contribute to the total transfer value? (deposit value including fee) - * @param coin_fee how much did the exchange charge for the deposit fee - * @param execution_time when was the transaction done, or - * when we expect it to be done (if @a wtid was NULL); - * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown - * to the exchange - */ -static void -handle_wtid_data (void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time) -{ - struct DepositWtidContext *ctx = cls; - - if (NULL == wtid) - { - ctx->pending = GNUNET_YES; - ctx->execution_time = execution_time; - return; - } - if (GNUNET_SYSERR == - TALER_amount_subtract (&ctx->coin_delta, - coin_contribution, - coin_fee)) - { - GNUNET_break (0); - ctx->pending = GNUNET_SYSERR; - return; - } - ctx->wtid = *wtid; - ctx->execution_time = execution_time; - ctx->coin_contribution = *coin_contribution; - ctx->coin_fee = *coin_fee; -} - - -/** - * Execute a "/track/transaction". Returns the transfer information - * associated with the given deposit. - * - * If it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. - * - * @param cls closure of type `struct DepositWtidContext *` - * @param connection MHD request which triggered the transaction - * @param session database session to use - * @param[out] mhd_ret set to MHD response status for @a connection, - * if transaction failed (!) - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -track_transaction_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - int *mhd_ret) -{ - struct DepositWtidContext *ctx = cls; - enum GNUNET_DB_QueryStatus qs; - - qs = TEH_plugin->wire_lookup_deposit_wtid (TEH_plugin->cls, - session, - &ctx->tps->h_contract_terms, - &ctx->tps->h_wire, - &ctx->tps->coin_pub, - ctx->merchant_pub, - &handle_wtid_data, - ctx); - if (0 > qs) - { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED, - "failed to fetch transaction data"); - } - return qs; - } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) - { - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_TRACK_TRANSACTION_NOT_FOUND, - "transaction unknown"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - return qs; -} - - -/** - * Check the merchant signature, and if it is valid, - * return the wire transfer identifier. - * - * @param connection the MHD connection to handle - * @param tps signed request to execute - * @param merchant_pub public key from the merchant - * @param merchant_sig signature from the merchant (to be checked) - * @return MHD result code - */ -static int -check_and_handle_track_transaction_request (struct MHD_Connection *connection, - const struct - TALER_DepositTrackPS *tps, - const struct - TALER_MerchantPublicKeyP * - merchant_pub, - const struct - TALER_MerchantSignatureP * - merchant_sig) -{ - struct DepositWtidContext ctx; - int mhd_ret; - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION, - &tps->purpose, - &merchant_sig->eddsa_sig, - &merchant_pub->eddsa_pub)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID, - "merchant_sig"); - } - ctx.pending = GNUNET_NO; - ctx.tps = tps; - ctx.merchant_pub = merchant_pub; - - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "handle track transaction", - &mhd_ret, - &track_transaction_transaction, - &ctx)) - return mhd_ret; - if (GNUNET_YES == ctx.pending) - return reply_transfer_pending (connection, - ctx.execution_time); - if (GNUNET_SYSERR == ctx.pending) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT, - "fees are inconsistent"); - return reply_track_transaction (connection, - &tps->h_contract_terms, - &tps->h_wire, - &tps->coin_pub, - &ctx.coin_delta, - &ctx.wtid, - ctx.execution_time); -} - - -/** - * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB" - * request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 4, contains: - * h_wire, merchant_pub, h_contract_terms and coin_pub) - * @return MHD result code - */ -int -TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[4]) -{ - int res; - struct TALER_DepositTrackPS tps; - struct TALER_MerchantSignatureP merchant_sig; - - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[0], - strlen (args[0]), - &tps.h_wire, - sizeof (tps.h_wire))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_DEPOSITS_INVALID_H_WIRE, - "wire hash malformed"); - } - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[1], - strlen (args[1]), - &tps.merchant, - sizeof (tps.merchant))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB, - "merchant public key malformed"); - } - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[2], - strlen (args[2]), - &tps.h_contract_terms, - sizeof (tps.h_contract_terms))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS, - "contract terms hash malformed"); - } - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[3], - strlen (args[3]), - &tps.coin_pub, - sizeof (tps.coin_pub))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_DEPOSITS_INVALID_COIN_PUB, - "coin public key malformed"); - } - res = TALER_MHD_parse_request_arg_data (connection, - "merchant_sig", - &merchant_sig, - sizeof (merchant_sig)); - if (GNUNET_SYSERR == res) - return MHD_NO; /* internal error */ - if (GNUNET_NO == res) - return MHD_YES; /* parse error */ - tps.purpose.size = htonl (sizeof (struct TALER_DepositTrackPS)); - tps.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION); - return check_and_handle_track_transaction_request (connection, - &tps, - &tps.merchant, - &merchant_sig); -} - - -/* end of taler-exchange-httpd_track_transaction.c */ diff --git a/src/exchange/taler-exchange-httpd_track_transaction.h b/src/exchange/taler-exchange-httpd_track_transaction.h deleted file mode 100644 index 5f54754f3..000000000 --- a/src/exchange/taler-exchange-httpd_track_transaction.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2017 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_track_transaction.h - * @brief Handle wire transfer tracking-related requests - * @author Christian Grothoff - */ -#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H -#define TALER_EXCHANGE_HTTPD_TRACK_TRANSACTION_H - -#include -#include -#include "taler-exchange-httpd.h" - - -/** - * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB" - * request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 4, contains: - * h_wire, merchant_pub, h_contract_terms and coin_pub) - * @return MHD result code - */ -int -TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[4]); - - -#endif diff --git a/src/exchange/taler-exchange-httpd_track_transfer.c b/src/exchange/taler-exchange-httpd_track_transfer.c deleted file mode 100644 index cff6045ef..000000000 --- a/src/exchange/taler-exchange-httpd_track_transfer.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2018 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_track_transfer.c - * @brief Handle wire transfer /track/transfer requests - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include -#include -#include -#include "taler_signatures.h" -#include "taler-exchange-httpd_keystate.h" -#include "taler-exchange-httpd_track_transfer.h" -#include "taler-exchange-httpd_responses.h" -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" - - -/** - * Detail for /wire/deposit response. - */ -struct TEH_TrackTransferDetail -{ - - /** - * We keep deposit details in a DLL. - */ - struct TEH_TrackTransferDetail *next; - - /** - * We keep deposit details in a DLL. - */ - struct TEH_TrackTransferDetail *prev; - - /** - * Hash of the proposal data. - */ - struct GNUNET_HashCode h_contract_terms; - - /** - * Coin's public key. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Total value of the coin. - */ - struct TALER_Amount deposit_value; - - /** - * Fees charged by the exchange for the deposit. - */ - struct TALER_Amount deposit_fee; -}; - - -/** - * A merchant asked for transaction details about a wire transfer. - * Provide them. Generates the 200 reply. - * - * @param connection connection to the client - * @param total total amount that was transferred - * @param merchant_pub public key of the merchant - * @param h_wire destination account - * @param wire_fee wire fee that was charged - * @param exec_time execution time of the wire transfer - * @param wdd_head linked list with details about the combined deposits - * @return MHD result code - */ -static int -reply_track_transfer_details (struct MHD_Connection *connection, - const struct TALER_Amount *total, - const struct - TALER_MerchantPublicKeyP *merchant_pub, - const struct GNUNET_HashCode *h_wire, - const struct TALER_Amount *wire_fee, - struct GNUNET_TIME_Absolute exec_time, - const struct TEH_TrackTransferDetail *wdd_head) -{ - const struct TEH_TrackTransferDetail *wdd_pos; - json_t *deposits; - struct TALER_WireDepositDetailP dd; - struct GNUNET_HashContext *hash_context; - struct TALER_WireDepositDataPS wdp; - struct TALER_ExchangePublicKeyP pub; - struct TALER_ExchangeSignatureP sig; - - GNUNET_TIME_round_abs (&exec_time); - deposits = json_array (); - hash_context = GNUNET_CRYPTO_hash_context_start (); - for (wdd_pos = wdd_head; NULL != wdd_pos; wdd_pos = wdd_pos->next) - { - dd.h_contract_terms = wdd_pos->h_contract_terms; - dd.execution_time = GNUNET_TIME_absolute_hton (exec_time); - dd.coin_pub = wdd_pos->coin_pub; - TALER_amount_hton (&dd.deposit_value, - &wdd_pos->deposit_value); - TALER_amount_hton (&dd.deposit_fee, - &wdd_pos->deposit_fee); - GNUNET_CRYPTO_hash_context_read (hash_context, - &dd, - sizeof (struct TALER_WireDepositDetailP)); - GNUNET_assert (0 == - json_array_append_new (deposits, - json_pack ("{s:o, s:o, s:o, s:o}", - "h_contract_terms", - GNUNET_JSON_from_data_auto ( - &wdd_pos-> - h_contract_terms), - "coin_pub", - GNUNET_JSON_from_data_auto ( - &wdd_pos->coin_pub), - "deposit_value", - TALER_JSON_from_amount ( - &wdd_pos->deposit_value), - "deposit_fee", - TALER_JSON_from_amount ( - &wdd_pos->deposit_fee)))); - } - wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); - wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); - TALER_amount_hton (&wdp.total, - total); - TALER_amount_hton (&wdp.wire_fee, - wire_fee); - wdp.merchant_pub = *merchant_pub; - wdp.h_wire = *h_wire; - GNUNET_CRYPTO_hash_context_finish (hash_context, - &wdp.h_details); - if (GNUNET_OK != - TEH_KS_sign (&wdp.purpose, - &pub, - &sig)) - { - json_decref (deposits); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_BAD_CONFIGURATION, - "no keys"); - } - - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}", - "total", TALER_JSON_from_amount (total), - "wire_fee", TALER_JSON_from_amount ( - wire_fee), - "merchant_pub", - GNUNET_JSON_from_data_auto ( - merchant_pub), - "h_wire", GNUNET_JSON_from_data_auto ( - h_wire), - "execution_time", - GNUNET_JSON_from_time_abs (exec_time), - "deposits", deposits, - "exchange_sig", - GNUNET_JSON_from_data_auto (&sig), - "exchange_pub", - GNUNET_JSON_from_data_auto (&pub)); -} - - -/** - * Closure for #handle_transaction_data. - */ -struct WtidTransactionContext -{ - - /** - * Identifier of the wire transfer to track. - */ - struct TALER_WireTransferIdentifierRawP wtid; - - /** - * Total amount of the wire transfer, as calculated by - * summing up the individual amounts. To be rounded down - * to calculate the real transfer amount at the end. - * Only valid if @e is_valid is #GNUNET_YES. - */ - struct TALER_Amount total; - - /** - * Public key of the merchant, only valid if @e is_valid - * is #GNUNET_YES. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Which method was used to wire the funds? - */ - char *wire_method; - - /** - * Hash of the wire details of the merchant (identical for all - * deposits), only valid if @e is_valid is #GNUNET_YES. - */ - struct GNUNET_HashCode h_wire; - - /** - * Wire fee applicable at @e exec_time. - */ - struct TALER_Amount wire_fee; - - /** - * Execution time of the wire transfer - */ - struct GNUNET_TIME_Absolute exec_time; - - /** - * Head of DLL with details for /wire/deposit response. - */ - struct TEH_TrackTransferDetail *wdd_head; - - /** - * Head of DLL with details for /wire/deposit response. - */ - struct TEH_TrackTransferDetail *wdd_tail; - - /** - * JSON array with details about the individual deposits. - */ - json_t *deposits; - - /** - * Initially #GNUNET_NO, if we found no deposits so far. Set to - * #GNUNET_YES if we got transaction data, and the database replies - * remained consistent with respect to @e merchant_pub and @e h_wire - * (as they should). Set to #GNUNET_SYSERR if we encountered an - * internal error. - */ - int is_valid; - -}; - - -/** - * Function called with the results of the lookup of the - * transaction data for the given wire transfer identifier. - * - * @param cls our context for transmission - * @param rowid which row in the DB is the information from (for diagnostics), ignored - * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) - * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls) - * @param wire where the funds were sent - * @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls) - * @param h_contract_terms which proposal was this payment about - * @param denom_pub denomination public key of the @a coin_pub (ignored) - * @param coin_pub which public key was this payment about - * @param deposit_value amount contributed by this coin in total - * @param deposit_fee deposit fee charged by exchange for this coin - */ -static void -handle_transaction_data (void *cls, - uint64_t rowid, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct GNUNET_HashCode *h_wire, - const json_t *wire, - struct GNUNET_TIME_Absolute exec_time, - const struct GNUNET_HashCode *h_contract_terms, - const struct TALER_DenominationPublicKey *denom_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *deposit_value, - const struct TALER_Amount *deposit_fee) -{ - struct WtidTransactionContext *ctx = cls; - struct TALER_Amount delta; - struct TEH_TrackTransferDetail *wdd; - char *wire_method; - - (void) rowid; - (void) denom_pub; - if (GNUNET_SYSERR == ctx->is_valid) - return; - if (NULL == (wire_method = TALER_JSON_wire_to_method (wire))) - { - GNUNET_break (0); - ctx->is_valid = GNUNET_SYSERR; - return; - } - if (GNUNET_NO == ctx->is_valid) - { - ctx->merchant_pub = *merchant_pub; - ctx->h_wire = *h_wire; - ctx->exec_time = exec_time; - ctx->wire_method = wire_method; - ctx->is_valid = GNUNET_YES; - if (GNUNET_OK != - TALER_amount_subtract (&ctx->total, - deposit_value, - deposit_fee)) - { - GNUNET_break (0); - ctx->is_valid = GNUNET_SYSERR; - return; - } - } - else - { - if ( (0 != GNUNET_memcmp (&ctx->merchant_pub, - merchant_pub)) || - (0 != strcmp (wire_method, - ctx->wire_method)) || - (0 != GNUNET_memcmp (&ctx->h_wire, - h_wire)) ) - { - GNUNET_break (0); - ctx->is_valid = GNUNET_SYSERR; - GNUNET_free (wire_method); - return; - } - GNUNET_free (wire_method); - if (GNUNET_OK != - TALER_amount_subtract (&delta, - deposit_value, - deposit_fee)) - { - GNUNET_break (0); - ctx->is_valid = GNUNET_SYSERR; - return; - } - if (GNUNET_OK != - TALER_amount_add (&ctx->total, - &ctx->total, - &delta)) - { - GNUNET_break (0); - ctx->is_valid = GNUNET_SYSERR; - return; - } - } - wdd = GNUNET_new (struct TEH_TrackTransferDetail); - wdd->deposit_value = *deposit_value; - wdd->deposit_fee = *deposit_fee; - wdd->h_contract_terms = *h_contract_terms; - wdd->coin_pub = *coin_pub; - GNUNET_CONTAINER_DLL_insert (ctx->wdd_head, - ctx->wdd_tail, - wdd); -} - - -/** - * Execute a "/track/transfer". Returns the transaction information - * associated with the given wire transfer identifier. - * - * If it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. - * - * @param cls closure - * @param connection MHD request which triggered the transaction - * @param session database session to use - * @param[out] mhd_ret set to MHD response status for @a connection, - * if transaction failed (!) - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -track_transfer_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - int *mhd_ret) -{ - struct WtidTransactionContext *ctx = cls; - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_TIME_Absolute wire_fee_start_date; - struct GNUNET_TIME_Absolute wire_fee_end_date; - struct TALER_MasterSignatureP wire_fee_master_sig; - struct TALER_Amount closing_fee; - - ctx->is_valid = GNUNET_NO; - ctx->wdd_head = NULL; - ctx->wdd_tail = NULL; - ctx->wire_method = NULL; - qs = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls, - session, - &ctx->wtid, - &handle_transaction_data, - ctx); - if (0 > qs) - { - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED, - "failed to fetch transaction data"); - } - return qs; - } - if (GNUNET_SYSERR == ctx->is_valid) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT, - "exchange database internally inconsistent"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - if (GNUNET_NO == ctx->is_valid) - { - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND, - "wtid"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - qs = TEH_plugin->get_wire_fee (TEH_plugin->cls, - session, - ctx->wire_method, - ctx->exec_time, - &wire_fee_start_date, - &wire_fee_end_date, - &ctx->wire_fee, - &closing_fee, - &wire_fee_master_sig); - if (0 >= qs) - { - if ( (GNUNET_DB_STATUS_HARD_ERROR == qs) || - (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS) ) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND, - "did not find wire fee"); - } - return qs; - } - if (GNUNET_OK != - TALER_amount_subtract (&ctx->total, - &ctx->total, - &ctx->wire_fee)) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT, - "could not subtract wire fee"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; -} - - -/** - * Free data structure reachable from @a ctx, but not @a ctx itself. - * - * @param ctx context to free - */ -static void -free_ctx (struct WtidTransactionContext *ctx) -{ - struct TEH_TrackTransferDetail *wdd; - - while (NULL != (wdd = ctx->wdd_head)) - { - GNUNET_CONTAINER_DLL_remove (ctx->wdd_head, - ctx->wdd_tail, - wdd); - GNUNET_free (wdd); - } - GNUNET_free_non_null (ctx->wire_method); -} - - -/** - * Handle a GET "/transfers/$WTID" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 1, just the wtid) - * @return MHD result code - */ -int -TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[1]) -{ - struct WtidTransactionContext ctx; - int mhd_ret; - - (void) rh; - memset (&ctx, - 0, - sizeof (ctx)); - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (args[0], - strlen (args[0]), - &ctx.wtid, - sizeof (ctx.wtid))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_TRANSFERS_INVALID_WTID, - "wire transfer identifier malformed"); - } - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "run track transfer", - &mhd_ret, - &track_transfer_transaction, - &ctx)) - { - free_ctx (&ctx); - return mhd_ret; - } - mhd_ret = reply_track_transfer_details (connection, - &ctx.total, - &ctx.merchant_pub, - &ctx.h_wire, - &ctx.wire_fee, - ctx.exec_time, - ctx.wdd_head); - free_ctx (&ctx); - return mhd_ret; -} - - -/* end of taler-exchange-httpd_track_transfer.c */ diff --git a/src/exchange/taler-exchange-httpd_track_transfer.h b/src/exchange/taler-exchange-httpd_track_transfer.h deleted file mode 100644 index c6bd7c5d2..000000000 --- a/src/exchange/taler-exchange-httpd_track_transfer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2017 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see -*/ -/** - * @file taler-exchange-httpd_track_transfer.h - * @brief Handle wire transfer tracking-related requests - * @author Christian Grothoff - */ -#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H -#define TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H - -#include -#include -#include "taler-exchange-httpd.h" - - -/** - * Handle a GET "/transfers/$WTID" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 1, just the wtid) - * @return MHD result code - */ -int -TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[1]); - - -#endif diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c b/src/exchange/taler-exchange-httpd_transfers_get.c new file mode 100644 index 000000000..713b43a58 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_transfers_get.c @@ -0,0 +1,538 @@ +/* + This file is part of TALER + Copyright (C) 2014-2018 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_transfers_get.c + * @brief Handle wire transfer /track/transfer requests + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include +#include +#include +#include "taler_signatures.h" +#include "taler-exchange-httpd_keystate.h" +#include "taler-exchange-httpd_transfers_get.h" +#include "taler-exchange-httpd_responses.h" +#include "taler_json_lib.h" +#include "taler_mhd_lib.h" + + +/** + * Detail for /wire/deposit response. + */ +struct TEH_TrackTransferDetail +{ + + /** + * We keep deposit details in a DLL. + */ + struct TEH_TrackTransferDetail *next; + + /** + * We keep deposit details in a DLL. + */ + struct TEH_TrackTransferDetail *prev; + + /** + * Hash of the proposal data. + */ + struct GNUNET_HashCode h_contract_terms; + + /** + * Coin's public key. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Total value of the coin. + */ + struct TALER_Amount deposit_value; + + /** + * Fees charged by the exchange for the deposit. + */ + struct TALER_Amount deposit_fee; +}; + + +/** + * A merchant asked for transaction details about a wire transfer. + * Provide them. Generates the 200 reply. + * + * @param connection connection to the client + * @param total total amount that was transferred + * @param merchant_pub public key of the merchant + * @param h_wire destination account + * @param wire_fee wire fee that was charged + * @param exec_time execution time of the wire transfer + * @param wdd_head linked list with details about the combined deposits + * @return MHD result code + */ +static int +reply_track_transfer_details (struct MHD_Connection *connection, + const struct TALER_Amount *total, + const struct + TALER_MerchantPublicKeyP *merchant_pub, + const struct GNUNET_HashCode *h_wire, + const struct TALER_Amount *wire_fee, + struct GNUNET_TIME_Absolute exec_time, + const struct TEH_TrackTransferDetail *wdd_head) +{ + const struct TEH_TrackTransferDetail *wdd_pos; + json_t *deposits; + struct TALER_WireDepositDetailP dd; + struct GNUNET_HashContext *hash_context; + struct TALER_WireDepositDataPS wdp; + struct TALER_ExchangePublicKeyP pub; + struct TALER_ExchangeSignatureP sig; + + GNUNET_TIME_round_abs (&exec_time); + deposits = json_array (); + hash_context = GNUNET_CRYPTO_hash_context_start (); + for (wdd_pos = wdd_head; NULL != wdd_pos; wdd_pos = wdd_pos->next) + { + dd.h_contract_terms = wdd_pos->h_contract_terms; + dd.execution_time = GNUNET_TIME_absolute_hton (exec_time); + dd.coin_pub = wdd_pos->coin_pub; + TALER_amount_hton (&dd.deposit_value, + &wdd_pos->deposit_value); + TALER_amount_hton (&dd.deposit_fee, + &wdd_pos->deposit_fee); + GNUNET_CRYPTO_hash_context_read (hash_context, + &dd, + sizeof (struct TALER_WireDepositDetailP)); + GNUNET_assert (0 == + json_array_append_new (deposits, + json_pack ("{s:o, s:o, s:o, s:o}", + "h_contract_terms", + GNUNET_JSON_from_data_auto ( + &wdd_pos-> + h_contract_terms), + "coin_pub", + GNUNET_JSON_from_data_auto ( + &wdd_pos->coin_pub), + "deposit_value", + TALER_JSON_from_amount ( + &wdd_pos->deposit_value), + "deposit_fee", + TALER_JSON_from_amount ( + &wdd_pos->deposit_fee)))); + } + wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); + wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); + TALER_amount_hton (&wdp.total, + total); + TALER_amount_hton (&wdp.wire_fee, + wire_fee); + wdp.merchant_pub = *merchant_pub; + wdp.h_wire = *h_wire; + GNUNET_CRYPTO_hash_context_finish (hash_context, + &wdp.h_details); + if (GNUNET_OK != + TEH_KS_sign (&wdp.purpose, + &pub, + &sig)) + { + json_decref (deposits); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } + + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}", + "total", TALER_JSON_from_amount (total), + "wire_fee", TALER_JSON_from_amount ( + wire_fee), + "merchant_pub", + GNUNET_JSON_from_data_auto ( + merchant_pub), + "h_wire", GNUNET_JSON_from_data_auto ( + h_wire), + "execution_time", + GNUNET_JSON_from_time_abs (exec_time), + "deposits", deposits, + "exchange_sig", + GNUNET_JSON_from_data_auto (&sig), + "exchange_pub", + GNUNET_JSON_from_data_auto (&pub)); +} + + +/** + * Closure for #handle_transaction_data. + */ +struct WtidTransactionContext +{ + + /** + * Identifier of the wire transfer to track. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * Total amount of the wire transfer, as calculated by + * summing up the individual amounts. To be rounded down + * to calculate the real transfer amount at the end. + * Only valid if @e is_valid is #GNUNET_YES. + */ + struct TALER_Amount total; + + /** + * Public key of the merchant, only valid if @e is_valid + * is #GNUNET_YES. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Which method was used to wire the funds? + */ + char *wire_method; + + /** + * Hash of the wire details of the merchant (identical for all + * deposits), only valid if @e is_valid is #GNUNET_YES. + */ + struct GNUNET_HashCode h_wire; + + /** + * Wire fee applicable at @e exec_time. + */ + struct TALER_Amount wire_fee; + + /** + * Execution time of the wire transfer + */ + struct GNUNET_TIME_Absolute exec_time; + + /** + * Head of DLL with details for /wire/deposit response. + */ + struct TEH_TrackTransferDetail *wdd_head; + + /** + * Head of DLL with details for /wire/deposit response. + */ + struct TEH_TrackTransferDetail *wdd_tail; + + /** + * JSON array with details about the individual deposits. + */ + json_t *deposits; + + /** + * Initially #GNUNET_NO, if we found no deposits so far. Set to + * #GNUNET_YES if we got transaction data, and the database replies + * remained consistent with respect to @e merchant_pub and @e h_wire + * (as they should). Set to #GNUNET_SYSERR if we encountered an + * internal error. + */ + int is_valid; + +}; + + +/** + * Function called with the results of the lookup of the + * transaction data for the given wire transfer identifier. + * + * @param cls our context for transmission + * @param rowid which row in the DB is the information from (for diagnostics), ignored + * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) + * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls) + * @param wire where the funds were sent + * @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls) + * @param h_contract_terms which proposal was this payment about + * @param denom_pub denomination public key of the @a coin_pub (ignored) + * @param coin_pub which public key was this payment about + * @param deposit_value amount contributed by this coin in total + * @param deposit_fee deposit fee charged by exchange for this coin + */ +static void +handle_transaction_data (void *cls, + uint64_t rowid, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct GNUNET_HashCode *h_wire, + const json_t *wire, + struct GNUNET_TIME_Absolute exec_time, + const struct GNUNET_HashCode *h_contract_terms, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *deposit_value, + const struct TALER_Amount *deposit_fee) +{ + struct WtidTransactionContext *ctx = cls; + struct TALER_Amount delta; + struct TEH_TrackTransferDetail *wdd; + char *wire_method; + + (void) rowid; + (void) denom_pub; + if (GNUNET_SYSERR == ctx->is_valid) + return; + if (NULL == (wire_method = TALER_JSON_wire_to_method (wire))) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + if (GNUNET_NO == ctx->is_valid) + { + ctx->merchant_pub = *merchant_pub; + ctx->h_wire = *h_wire; + ctx->exec_time = exec_time; + ctx->wire_method = wire_method; + ctx->is_valid = GNUNET_YES; + if (GNUNET_OK != + TALER_amount_subtract (&ctx->total, + deposit_value, + deposit_fee)) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + } + else + { + if ( (0 != GNUNET_memcmp (&ctx->merchant_pub, + merchant_pub)) || + (0 != strcmp (wire_method, + ctx->wire_method)) || + (0 != GNUNET_memcmp (&ctx->h_wire, + h_wire)) ) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + GNUNET_free (wire_method); + return; + } + GNUNET_free (wire_method); + if (GNUNET_OK != + TALER_amount_subtract (&delta, + deposit_value, + deposit_fee)) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + if (GNUNET_OK != + TALER_amount_add (&ctx->total, + &ctx->total, + &delta)) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + } + wdd = GNUNET_new (struct TEH_TrackTransferDetail); + wdd->deposit_value = *deposit_value; + wdd->deposit_fee = *deposit_fee; + wdd->h_contract_terms = *h_contract_terms; + wdd->coin_pub = *coin_pub; + GNUNET_CONTAINER_DLL_insert (ctx->wdd_head, + ctx->wdd_tail, + wdd); +} + + +/** + * Execute a "/track/transfer". Returns the transaction information + * associated with the given wire transfer identifier. + * + * If it returns a non-error code, the transaction logic MUST + * NOT queue a MHD response. IF it returns an hard error, the + * transaction logic MUST queue a MHD response and set @a mhd_ret. IF + * it returns the soft error code, the function MAY be called again to + * retry and MUST not queue a MHD response. + * + * @param cls closure + * @param connection MHD request which triggered the transaction + * @param session database session to use + * @param[out] mhd_ret set to MHD response status for @a connection, + * if transaction failed (!) + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +track_transfer_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *mhd_ret) +{ + struct WtidTransactionContext *ctx = cls; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Absolute wire_fee_start_date; + struct GNUNET_TIME_Absolute wire_fee_end_date; + struct TALER_MasterSignatureP wire_fee_master_sig; + struct TALER_Amount closing_fee; + + ctx->is_valid = GNUNET_NO; + ctx->wdd_head = NULL; + ctx->wdd_tail = NULL; + ctx->wire_method = NULL; + qs = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls, + session, + &ctx->wtid, + &handle_transaction_data, + ctx); + if (0 > qs) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED, + "failed to fetch transaction data"); + } + return qs; + } + if (GNUNET_SYSERR == ctx->is_valid) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT, + "exchange database internally inconsistent"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (GNUNET_NO == ctx->is_valid) + { + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND, + "wtid"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + qs = TEH_plugin->get_wire_fee (TEH_plugin->cls, + session, + ctx->wire_method, + ctx->exec_time, + &wire_fee_start_date, + &wire_fee_end_date, + &ctx->wire_fee, + &closing_fee, + &wire_fee_master_sig); + if (0 >= qs) + { + if ( (GNUNET_DB_STATUS_HARD_ERROR == qs) || + (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS) ) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND, + "did not find wire fee"); + } + return qs; + } + if (GNUNET_OK != + TALER_amount_subtract (&ctx->total, + &ctx->total, + &ctx->wire_fee)) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT, + "could not subtract wire fee"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; +} + + +/** + * Free data structure reachable from @a ctx, but not @a ctx itself. + * + * @param ctx context to free + */ +static void +free_ctx (struct WtidTransactionContext *ctx) +{ + struct TEH_TrackTransferDetail *wdd; + + while (NULL != (wdd = ctx->wdd_head)) + { + GNUNET_CONTAINER_DLL_remove (ctx->wdd_head, + ctx->wdd_tail, + wdd); + GNUNET_free (wdd); + } + GNUNET_free_non_null (ctx->wire_method); +} + + +/** + * Handle a GET "/transfers/$WTID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 1, just the wtid) + * @return MHD result code + */ +int +TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[1]) +{ + struct WtidTransactionContext ctx; + int mhd_ret; + + (void) rh; + memset (&ctx, + 0, + sizeof (ctx)); + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[0], + strlen (args[0]), + &ctx.wtid, + sizeof (ctx.wtid))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_TRANSFERS_INVALID_WTID, + "wire transfer identifier malformed"); + } + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "run track transfer", + &mhd_ret, + &track_transfer_transaction, + &ctx)) + { + free_ctx (&ctx); + return mhd_ret; + } + mhd_ret = reply_track_transfer_details (connection, + &ctx.total, + &ctx.merchant_pub, + &ctx.h_wire, + &ctx.wire_fee, + ctx.exec_time, + ctx.wdd_head); + free_ctx (&ctx); + return mhd_ret; +} + + +/* end of taler-exchange-httpd_transfers_get.c */ diff --git a/src/exchange/taler-exchange-httpd_transfers_get.h b/src/exchange/taler-exchange-httpd_transfers_get.h new file mode 100644 index 000000000..0f9e21a5e --- /dev/null +++ b/src/exchange/taler-exchange-httpd_transfers_get.h @@ -0,0 +1,43 @@ +/* + This file is part of TALER + Copyright (C) 2014-2017 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_transfers_get.h + * @brief Handle wire transfer tracking-related requests + * @author Christian Grothoff + */ +#ifndef TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H +#define TALER_EXCHANGE_HTTPD_TRACK_TRANSFER_H + +#include +#include +#include "taler-exchange-httpd.h" + + +/** + * Handle a GET "/transfers/$WTID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 1, just the wtid) + * @return MHD result code + */ +int +TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[1]); + + +#endif diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c new file mode 100644 index 000000000..33308dce2 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -0,0 +1,509 @@ +/* + This file is part of TALER + Copyright (C) 2014-2019 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 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General + Public License along with TALER; see the file COPYING. If not, + see +*/ +/** + * @file taler-exchange-httpd_withdraw.c + * @brief Handle /reserve/withdraw requests + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include +#include "taler_json_lib.h" +#include "taler_mhd_lib.h" +#include "taler-exchange-httpd_withdraw.h" +#include "taler-exchange-httpd_responses.h" +#include "taler-exchange-httpd_keystate.h" + + +/** + * Perform RSA signature before checking with the database? + * Reduces time spent in transaction, but may cause us to + * waste CPU time if DB check fails. + */ +#define OPTIMISTIC_SIGN 1 + + +/** + * Send reserve status information to client with the + * message that we have insufficient funds for the + * requested /reserve/withdraw operation. + * + * @param connection connection to the client + * @param rh reserve history to return + * @return MHD result code + */ +static int +reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection, + const struct + TALER_EXCHANGEDB_ReserveHistory *rh) +{ + json_t *json_balance; + json_t *json_history; + struct TALER_Amount balance; + + json_history = TEH_RESPONSE_compile_reserve_history (rh, + &balance); + if ((NULL == json_history) + /* Address the case where the ptr is not null, but + * it fails "internally" to dump as string (= corrupted). */ + || (0 == json_dumpb (json_history, NULL, 0, 0))) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS, + "balance calculation failure"); + json_balance = TALER_JSON_from_amount (&balance); + + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_CONFLICT, + "{s:s, s:I, s:o, s:o}", + "hint", "insufficient funds", + "code", + (json_int_t) + TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS, + "balance", json_balance, + "history", json_history); +} + + +/** + * Send blinded coin information to client. + * + * @param connection connection to the client + * @param collectable blinded coin to return + * @return MHD result code + */ +static int +reply_reserve_withdraw_success (struct MHD_Connection *connection, + const struct + TALER_EXCHANGEDB_CollectableBlindcoin * + collectable) +{ + json_t *sig_json; + + sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature); + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o}", + "ev_sig", sig_json); +} + + +/** + * Context for #withdraw_transaction. + */ +struct WithdrawContext +{ + /** + * Details about the withdrawal request. + */ + struct TALER_WithdrawRequestPS wsrd; + + /** + * Value of the coin plus withdraw fee. + */ + struct TALER_Amount amount_required; + + /** + * Hash of the denomination public key. + */ + struct GNUNET_HashCode denom_pub_hash; + + /** + * Signature over the request. + */ + struct TALER_ReserveSignatureP signature; + + /** + * Blinded planchet. + */ + char *blinded_msg; + + /** + * Key state to use to inspect previous withdrawal values. + */ + struct TEH_KS_StateHandle *key_state; + + /** + * Number of bytes in @e blinded_msg. + */ + size_t blinded_msg_len; + + /** + * Details about denomination we are about to withdraw. + */ + struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; + + /** + * Set to the resulting signed coin data to be returned to the client. + */ + struct TALER_EXCHANGEDB_CollectableBlindcoin collectable; + +}; + + +/** + * Function implementing /reserve/withdraw transaction. Runs the + * transaction logic; IF it returns a non-error code, the transaction + * logic MUST NOT queue a MHD response. IF it returns an hard error, + * the transaction logic MUST queue a MHD response and set @a mhd_ret. + * IF it returns the soft error code, the function MAY be called again + * to retry and MUST not queue a MHD response. + * + * Note that "wc->collectable.sig" may already be set before entering + * this function, either because OPTIMISTIC_SIGN was used and we signed + * before entering the transaction, or because this function is run + * twice (!) by #TEH_DB_run_transaction() and the first time created + * the signature and then failed to commit. Furthermore, we may get + * a 2nd correct signature briefly if "get_withdraw_info" suceeds and + * finds one in the DB. To avoid signing twice, the function may + * return a valid signature in "wc->collectable.sig" even if it failed. + * The caller must thus free the signature in either case. + * + * @param cls a `struct WithdrawContext *` + * @param connection MHD request which triggered the transaction + * @param session database session to use + * @param[out] mhd_ret set to MHD response status for @a connection, + * if transaction failed (!) + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +withdraw_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *mhd_ret) +{ + struct WithdrawContext *wc = cls; + struct TALER_EXCHANGEDB_Reserve r; + enum GNUNET_DB_QueryStatus qs; + struct TALER_Amount fee_withdraw; + struct TALER_DenominationSignature denom_sig; + +#if OPTIMISTIC_SIGN + /* store away optimistic signature to protect + it from being overwritten by get_withdraw_info */ + denom_sig = wc->collectable.sig; + wc->collectable.sig.rsa_signature = NULL; +#endif + qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls, + session, + &wc->wsrd.h_coin_envelope, + &wc->collectable); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_DB_FETCH_ERROR, + "failed to fetch withdraw data"); + wc->collectable.sig = denom_sig; + return qs; + } + + /* Don't sign again if we have already signed the coin */ + if (1 == qs) + { +#if OPTIMISTIC_SIGN + GNUNET_CRYPTO_rsa_signature_free (denom_sig.rsa_signature); +#endif + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + } + GNUNET_assert (0 == qs); + wc->collectable.sig = denom_sig; + + /* Check if balance is sufficient */ + r.pub = wc->wsrd.reserve_pub; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Trying to withdraw from reserve: %s\n", + TALER_B2S (&r.pub)); + qs = TEH_plugin->reserve_get (TEH_plugin->cls, + session, + &r); + if (0 > qs) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_DB_FETCH_ERROR, + "failed to fetch reserve data"); + return qs; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_WITHDRAW_RESERVE_UNKNOWN, + "reserve_pub"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (0 < TALER_amount_cmp (&wc->amount_required, + &r.balance)) + { + char *amount_required; + char *r_balance; + struct TALER_EXCHANGEDB_ReserveHistory *rh; + /* The reserve does not have the required amount (actual + * amount + withdraw fee) */ + GNUNET_break_op (0); + amount_required = TALER_amount_to_string (&wc->amount_required); + r_balance = TALER_amount_to_string (&r.balance); + TALER_LOG_WARNING ("Asked %s over a reserve worth %s\n", + amount_required, + r_balance); + GNUNET_free (amount_required); + GNUNET_free (r_balance); + qs = TEH_plugin->get_reserve_history (TEH_plugin->cls, + session, + &wc->wsrd.reserve_pub, + &rh); + if (NULL == rh) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_DB_FETCH_ERROR, + "failed to fetch reserve history"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + *mhd_ret = reply_reserve_withdraw_insufficient_funds (connection, + rh); + TEH_plugin->free_reserve_history (TEH_plugin->cls, + rh); + return GNUNET_DB_STATUS_HARD_ERROR; + } + + /* Balance is good, sign the coin! */ +#if ! OPTIMISTIC_SIGN + if (NULL == wc->collectable.sig.rsa_signature) + { + wc->collectable.sig.rsa_signature + = GNUNET_CRYPTO_rsa_sign_blinded (wc->dki->denom_priv.rsa_private_key, + wc->blinded_msg, + wc->blinded_msg_len); + if (NULL == wc->collectable.sig.rsa_signature) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_SIGNATURE_FAILED, + "Failed to create signature"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + } +#endif + TALER_amount_ntoh (&fee_withdraw, + &wc->dki->issue.properties.fee_withdraw); + wc->collectable.denom_pub_hash = wc->denom_pub_hash; + wc->collectable.amount_with_fee = wc->amount_required; + wc->collectable.withdraw_fee = fee_withdraw; + wc->collectable.reserve_pub = wc->wsrd.reserve_pub; + wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope; + wc->collectable.reserve_sig = wc->signature; + qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls, + session, + &wc->collectable); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_DB_STORE_ERROR, + "failed to persist withdraw data"); + return qs; + } + return qs; +} + + +/** + * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the + * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which + * specifies the key/value of the coin to be withdrawn, and checks that the + * signature "reserve_sig" makes this a valid withdrawal request from the + * specified reserve. If so, the envelope with the blinded coin "coin_ev" is + * passed down to execute the withdrawl operation. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param root uploaded JSON data + * @param args array of additional options (first must be the + * reserve public key, the second one should be "withdraw") + * @return MHD result code + */ +int +TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const json_t *root, + const char *const args[2]) +{ + struct WithdrawContext wc; + int res; + int mhd_ret; + unsigned int hc; + enum TALER_ErrorCode ec; + struct TALER_Amount amount; + struct TALER_Amount fee_withdraw; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_varsize ("coin_ev", + (void **) &wc.blinded_msg, + &wc.blinded_msg_len), + GNUNET_JSON_spec_fixed_auto ("reserve_sig", + &wc.signature), + GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", + &wc.denom_pub_hash), + GNUNET_JSON_spec_end () + }; + + (void) rh; + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[0], + strlen (args[0]), + &wc.wsrd.reserve_pub, + sizeof (wc.wsrd.reserve_pub))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_RESERVES_INVALID_RESERVE_PUB, + "reserve public key malformed"); + } + + res = TALER_MHD_parse_json_data (connection, + root, + spec); + if (GNUNET_OK != res) + return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; + wc.key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); + if (NULL == wc.key_state) + { + TALER_LOG_ERROR ("Lacking keys to operate\n"); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } + wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state, + &wc.denom_pub_hash, + TEH_KS_DKU_WITHDRAW, + &ec, + &hc); + if (NULL == wc.dki) + { + GNUNET_JSON_parse_free (spec); + TEH_KS_release (wc.key_state); + return TALER_MHD_reply_with_error (connection, + hc, + ec, + "could not find denomination key"); + } + GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key); + TALER_amount_ntoh (&amount, + &wc.dki->issue.properties.value); + TALER_amount_ntoh (&fee_withdraw, + &wc.dki->issue.properties.fee_withdraw); + if (GNUNET_OK != + TALER_amount_add (&wc.amount_required, + &amount, + &fee_withdraw)) + { + GNUNET_JSON_parse_free (spec); + TEH_KS_release (wc.key_state); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW, + "amount overflow for value plus withdraw fee"); + } + TALER_amount_hton (&wc.wsrd.amount_with_fee, + &wc.amount_required); + TALER_amount_hton (&wc.wsrd.withdraw_fee, + &fee_withdraw); + /* verify signature! */ + wc.wsrd.purpose.size + = htonl (sizeof (struct TALER_WithdrawRequestPS)); + wc.wsrd.purpose.purpose + = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); + wc.wsrd.h_denomination_pub + = wc.denom_pub_hash; + GNUNET_CRYPTO_hash (wc.blinded_msg, + wc.blinded_msg_len, + &wc.wsrd.h_coin_envelope); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW, + &wc.wsrd.purpose, + &wc.signature.eddsa_signature, + &wc.wsrd.reserve_pub.eddsa_pub)) + { + TALER_LOG_WARNING ( + "Client supplied invalid signature for /reserve/withdraw request\n"); + GNUNET_JSON_parse_free (spec); + TEH_KS_release (wc.key_state); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID, + "reserve_sig"); + } + +#if OPTIMISTIC_SIGN + /* Sign before transaction! */ + wc.collectable.sig.rsa_signature + = GNUNET_CRYPTO_rsa_sign_blinded (wc.dki->denom_priv.rsa_private_key, + wc.blinded_msg, + wc.blinded_msg_len); + if (NULL == wc.collectable.sig.rsa_signature) + { + GNUNET_break (0); + GNUNET_JSON_parse_free (spec); + TEH_KS_release (wc.key_state); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_WITHDRAW_SIGNATURE_FAILED, + "Failed to sign"); + } +#endif + + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "run reserve withdraw", + &mhd_ret, + &withdraw_transaction, + &wc)) + { + TEH_KS_release (wc.key_state); + /* Even if #withdraw_transaction() failed, it may have created a signature + (or we might have done it optimistically above). */ + if (NULL != wc.collectable.sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature); + GNUNET_JSON_parse_free (spec); + return mhd_ret; + } + TEH_KS_release (wc.key_state); + GNUNET_JSON_parse_free (spec); + + mhd_ret = reply_reserve_withdraw_success (connection, + &wc.collectable); + GNUNET_CRYPTO_rsa_signature_free (wc.collectable.sig.rsa_signature); + return mhd_ret; +} + + +/* end of taler-exchange-httpd_withdraw.c */ diff --git a/src/exchange/taler-exchange-httpd_withdraw.h b/src/exchange/taler-exchange-httpd_withdraw.h new file mode 100644 index 000000000..cc820283f --- /dev/null +++ b/src/exchange/taler-exchange-httpd_withdraw.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2014-2020 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 + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file taler-exchange-httpd_withdraw.h + * @brief Handle /reserve/withdraw requests + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#ifndef TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H +#define TALER_EXCHANGE_HTTPD_RESERVE_WITHDRAW_H + +#include +#include "taler-exchange-httpd.h" + + +/** + * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the + * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which + * specifies the key/value of the coin to be withdrawn, and checks that the + * signature "reserve_sig" makes this a valid withdrawl request from the + * specified reserve. If so, the envelope with the blinded coin "coin_ev" is + * passed down to execute the withdrawl operation. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param root uploaded JSON data + * @param args array of additional options (first must be the + * reserve public key, the second one should be "withdraw") + * @return MHD result code + */ +int +TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const json_t *root, + const char *const args[2]); + +#endif diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 09eca8ed4..0696d96cd 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018 Taler Systems SA + Copyright (C) 2014-2020 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 @@ -493,19 +493,6 @@ TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys, const struct TALER_ExchangePublicKeyP *pub); -/** - * Lookup the given @a pub in @a keys. - * - * @param keys the exchange's key set - * @param pub claimed current online signing key for the exchange - * @return NULL if @a pub was not found - */ -const struct TALER_EXCHANGE_SigningPublicKey * -TALER_EXCHANGE_get_signing_key_details (const struct TALER_EXCHANGE_Keys *keys, - const struct - TALER_ExchangePublicKeyP *pub); - - /** * Get exchange's base URL. * @@ -574,11 +561,11 @@ TALER_EXCHANGE_get_denomination_key_by_hash (const struct * @return NULL on error (@a exchange_pub not known) */ const struct TALER_EXCHANGE_SigningPublicKey * -TALER_EXCHANGE_get_exchange_signing_key_info (const struct - TALER_EXCHANGE_Keys *keys, - const struct - TALER_ExchangePublicKeyP * - exchange_pub); +TALER_EXCHANGE_get_signing_key_info (const struct + TALER_EXCHANGE_Keys *keys, + const struct + TALER_ExchangePublicKeyP * + exchange_pub); /* ********************* /wire *********************** */ @@ -661,12 +648,12 @@ struct TALER_EXCHANGE_WireAccount * @param accounts list of wire accounts of the exchange, NULL on error */ typedef void -(*TALER_EXCHANGE_WireResultCallback) (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - unsigned int accounts_len, - const struct - TALER_EXCHANGE_WireAccount *accounts); +(*TALER_EXCHANGE_WireCallback) (void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + unsigned int accounts_len, + const struct + TALER_EXCHANGE_WireAccount *accounts); /** @@ -696,7 +683,7 @@ struct TALER_EXCHANGE_WireHandle; */ struct TALER_EXCHANGE_WireHandle * TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange, - TALER_EXCHANGE_WireResultCallback wire_cb, + TALER_EXCHANGE_WireCallback wire_cb, void *wire_cb_cls); @@ -833,12 +820,12 @@ struct TALER_EXCHANGE_RefundHandle; * be forwarded to the customer) */ typedef void -(*TALER_EXCHANGE_RefundResultCallback) (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - const struct - TALER_ExchangePublicKeyP *sign_key, - const json_t *obj); +(*TALER_EXCHANGE_RefundCallback) (void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + const struct + TALER_ExchangePublicKeyP *sign_key, + const json_t *obj); /** @@ -879,7 +866,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, const struct TALER_MerchantPrivateKeyP *merchant_priv, - TALER_EXCHANGE_RefundResultCallback cb, + TALER_EXCHANGE_RefundCallback cb, void *cb_cls); @@ -923,7 +910,7 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, uint64_t rtransaction_id, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantSignatureP *merchant_sig, - TALER_EXCHANGE_RefundResultCallback cb, + TALER_EXCHANGE_RefundCallback cb, void *cb_cls); @@ -945,7 +932,7 @@ TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund); /** * @brief A /reserve/status Handle */ -struct TALER_EXCHANGE_ReserveStatusHandle; +struct TALER_EXCHANGE_ReservesGetHandle; /** @@ -1116,16 +1103,16 @@ struct TALER_EXCHANGE_ReserveHistory * @param history detailed transaction history, NULL on error */ typedef void -(*TALER_EXCHANGE_ReserveStatusResultCallback) (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - const json_t *json, - const struct - TALER_Amount *balance, - unsigned int history_length, - const struct - TALER_EXCHANGE_ReserveHistory * - history); +(*TALER_EXCHANGE_ReservesGetCallback) (void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + const json_t *json, + const struct + TALER_Amount *balance, + unsigned int history_length, + const struct + TALER_EXCHANGE_ReserveHistory * + history); /** @@ -1144,12 +1131,12 @@ typedef void * @return a handle for this request; NULL if the inputs are invalid (i.e. * signatures fail to verify). In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveStatusHandle * -TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_ReservePublicKeyP *reserve_pub, - TALER_EXCHANGE_ReserveStatusResultCallback cb, - void *cb_cls); +struct TALER_EXCHANGE_ReservesGetHandle * +TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_ReservePublicKeyP *reserve_pub, + TALER_EXCHANGE_ReservesGetCallback cb, + void *cb_cls); /** @@ -1159,8 +1146,8 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange, * @param rsh the reserve status request handle */ void -TALER_EXCHANGE_reserve_status_cancel (struct - TALER_EXCHANGE_ReserveStatusHandle *rsh); +TALER_EXCHANGE_reserves_get_cancel (struct + TALER_EXCHANGE_ReservesGetHandle *rsh); /* ********************* /reserve/withdraw *********************** */ @@ -1169,7 +1156,7 @@ TALER_EXCHANGE_reserve_status_cancel (struct /** * @brief A /reserve/withdraw Handle */ -struct TALER_EXCHANGE_ReserveWithdrawHandle; +struct TALER_EXCHANGE_WithdrawHandle; /** @@ -1184,13 +1171,13 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle; * @param full_response full response from the exchange (for logging, in case of errors) */ typedef void -(*TALER_EXCHANGE_ReserveWithdrawResultCallback) (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - const struct - TALER_DenominationSignature * - sig, - const json_t *full_response); +(*TALER_EXCHANGE_WithdrawCallback) (void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + const struct + TALER_DenominationSignature * + sig, + const json_t *full_response); /** @@ -1214,15 +1201,15 @@ typedef void * if the inputs are invalid (i.e. denomination key not with this exchange). * In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveWithdrawHandle * -TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct - TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_PlanchetSecretsP *ps, - TALER_EXCHANGE_ReserveWithdrawResultCallback - res_cb, - void *res_cb_cls); +struct TALER_EXCHANGE_WithdrawHandle * +TALER_EXCHANGE_withdraw (struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_EXCHANGE_DenomPublicKey *pk, + const struct + TALER_ReservePrivateKeyP *reserve_priv, + const struct TALER_PlanchetSecretsP *ps, + TALER_EXCHANGE_WithdrawCallback + res_cb, + void *res_cb_cls); /** @@ -1247,18 +1234,18 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange, * if the inputs are invalid (i.e. denomination key not with this exchange). * In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveWithdrawHandle * -TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_EXCHANGE_DenomPublicKey *pk, - const struct - TALER_ReserveSignatureP *reserve_sig, - const struct - TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_PlanchetSecretsP *ps, - TALER_EXCHANGE_ReserveWithdrawResultCallback - res_cb, - void *res_cb_cls); +struct TALER_EXCHANGE_WithdrawHandle * +TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_EXCHANGE_DenomPublicKey *pk, + const struct + TALER_ReserveSignatureP *reserve_sig, + const struct + TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_PlanchetSecretsP *ps, + TALER_EXCHANGE_WithdrawCallback + res_cb, + void *res_cb_cls); /** @@ -1268,9 +1255,9 @@ TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, * @param sign the withdraw sign request handle */ void -TALER_EXCHANGE_reserve_withdraw_cancel (struct - TALER_EXCHANGE_ReserveWithdrawHandle * - sign); +TALER_EXCHANGE_withdraw_cancel (struct + TALER_EXCHANGE_WithdrawHandle * + sign); /* ********************* /refresh/melt+reveal ***************************** */ @@ -1551,12 +1538,12 @@ TALER_EXCHANGE_refresh_link_cancel (struct TALER_EXCHANGE_RefreshLinkHandle *rlh); -/* ********************* /track/transfer *********************** */ +/* ********************* /transfers/$WTID *********************** */ /** - * @brief A /track/transfer Handle + * @brief A /transfers/$WTID Handle */ -struct TALER_EXCHANGE_TrackTransferHandle; +struct TALER_EXCHANGE_TransfersGetHandle; /** @@ -1578,20 +1565,20 @@ struct TALER_EXCHANGE_TrackTransferHandle; * @param details array with details about the combined transactions */ typedef void -(*TALER_EXCHANGE_TrackTransferCallback)(void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - const struct - TALER_ExchangePublicKeyP *sign_key, - const json_t *json, - const struct GNUNET_HashCode *h_wire, - struct GNUNET_TIME_Absolute - execution_time, - const struct TALER_Amount *total_amount, - const struct TALER_Amount *wire_fee, - unsigned int details_length, - const struct - TALER_TrackTransferDetails *details); +(*TALER_EXCHANGE_TransfersGetCallback)(void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + const struct + TALER_ExchangePublicKeyP *sign_key, + const json_t *json, + const struct GNUNET_HashCode *h_wire, + struct GNUNET_TIME_Absolute + execution_time, + const struct TALER_Amount *total_amount, + const struct TALER_Amount *wire_fee, + unsigned int details_length, + const struct + TALER_TrackTransferDetails *details); /** @@ -1604,12 +1591,12 @@ typedef void * @param cb_cls closure for @a cb * @return handle to cancel operation */ -struct TALER_EXCHANGE_TrackTransferHandle * -TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_WireTransferIdentifierRawP *wtid, - TALER_EXCHANGE_TrackTransferCallback cb, - void *cb_cls); +struct TALER_EXCHANGE_TransfersGetHandle * +TALER_EXCHANGE_transfers_get (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_WireTransferIdentifierRawP *wtid, + TALER_EXCHANGE_TransfersGetCallback cb, + void *cb_cls); /** @@ -1619,17 +1606,17 @@ TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange, * @param wdh the wire deposits request handle */ void -TALER_EXCHANGE_track_transfer_cancel (struct - TALER_EXCHANGE_TrackTransferHandle *wdh); +TALER_EXCHANGE_transfers_get_cancel (struct + TALER_EXCHANGE_TransfersGetHandle *wdh); -/* ********************* /track/transaction *********************** */ +/* ********************* GET /deposits/ *********************** */ /** - * @brief A /track/transaction Handle + * @brief A /deposits/ GET Handle */ -struct TALER_EXCHANGE_TrackTransactionHandle; +struct TALER_EXCHANGE_DepositGetHandle; /** @@ -1647,19 +1634,19 @@ struct TALER_EXCHANGE_TrackTransactionHandle; * @param coin_contribution contribution to the total amount by this coin (can be NULL) */ typedef void -(*TALER_EXCHANGE_TrackTransactionCallback)(void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - const struct - TALER_ExchangePublicKeyP *sign_key, - const json_t *json, - const struct - TALER_WireTransferIdentifierRawP * - wtid, - struct GNUNET_TIME_Absolute - execution_time, - const struct - TALER_Amount *coin_contribution); +(*TALER_EXCHANGE_DepositGetCallback)(void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + const struct + TALER_ExchangePublicKeyP *sign_key, + const json_t *json, + const struct + TALER_WireTransferIdentifierRawP * + wtid, + struct GNUNET_TIME_Absolute + execution_time, + const struct + TALER_Amount *coin_contribution); /** @@ -1676,17 +1663,17 @@ typedef void * @param cb_cls closure for @a cb * @return handle to abort request */ -struct TALER_EXCHANGE_TrackTransactionHandle * -TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_MerchantPrivateKeyP *merchant_priv, - const struct GNUNET_HashCode *h_wire, - const struct - GNUNET_HashCode *h_contract_terms, - const struct - TALER_CoinSpendPublicKeyP *coin_pub, - TALER_EXCHANGE_TrackTransactionCallback cb, - void *cb_cls); +struct TALER_EXCHANGE_DepositGetHandle * +TALER_EXCHANGE_deposits_get (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_MerchantPrivateKeyP *merchant_priv, + const struct GNUNET_HashCode *h_wire, + const struct + GNUNET_HashCode *h_contract_terms, + const struct + TALER_CoinSpendPublicKeyP *coin_pub, + TALER_EXCHANGE_DepositGetCallback cb, + void *cb_cls); /** @@ -1696,9 +1683,9 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange, * @param dwh the wire deposits request handle */ void -TALER_EXCHANGE_track_transaction_cancel (struct - TALER_EXCHANGE_TrackTransactionHandle * - dwh); +TALER_EXCHANGE_deposits_get_cancel (struct + TALER_EXCHANGE_DepositGetHandle * + dwh); /** diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index ae02b3db2..d5f31b064 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -382,17 +382,17 @@ TALER_EXCHANGE_verify_coin_history (const struct * @return NULL on error (@a exchange_pub not known) */ const struct TALER_EXCHANGE_SigningPublicKey * -TALER_EXCHANGE_get_exchange_signing_key_info (const struct - TALER_EXCHANGE_Keys *keys, - const struct - TALER_ExchangePublicKeyP * - exchange_pub) +TALER_EXCHANGE_get_signing_key_info (const struct + TALER_EXCHANGE_Keys *keys, + const struct + TALER_ExchangePublicKeyP * + exchange_pub) { for (unsigned int i = 0; inum_sign_keys; i++) { - const struct TALER_EXCHANGE_SigningPublicKey *spk; + const struct TALER_EXCHANGE_SigningPublicKey *spk + = &keys->sign_keys[i]; - spk = &keys->sign_keys[i]; if (0 == GNUNET_memcmp (exchange_pub, &spk->key)) return spk; diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 06eeb6a2f..b1d0162f2 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -146,8 +146,8 @@ auditor_cb (void *cls, "Will provide deposit confirmation to auditor `%s'\n", TALER_B2S (auditor_pub)); key_state = TALER_EXCHANGE_get_keys (dh->exchange); - spk = TALER_EXCHANGE_get_signing_key_details (key_state, - &dh->exchange_pub); + spk = TALER_EXCHANGE_get_signing_key_info (key_state, + &dh->exchange_pub); GNUNET_assert (NULL != spk); TALER_amount_ntoh (&amount_without_fee, &dh->depconf.amount_without_fee); diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 783cddea2..6a88b703b 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -2037,30 +2037,6 @@ TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange) } -/** - * Lookup the given @a pub in @a keys. - * - * @param keys the exchange's key set - * @param pub claimed current online signing key for the exchange - * @return NULL if @a pub was not found - */ -const struct TALER_EXCHANGE_SigningPublicKey * -TALER_EXCHANGE_get_signing_key_details (const struct TALER_EXCHANGE_Keys *keys, - const struct - TALER_ExchangePublicKeyP *pub) -{ - for (unsigned int i = 0; inum_sign_keys; i++) - { - struct TALER_EXCHANGE_SigningPublicKey *spk = &keys->sign_keys[i]; - - if (0 == GNUNET_memcmp (pub, - &spk->key)) - return spk; - } - return NULL; -} - - /** * Test if the given @a pub is a the current signing key from the exchange * according to @a keys. diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 8f2c0c4dc..e986f1020 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -62,7 +62,7 @@ struct TALER_EXCHANGE_RefundHandle /** * Function to call with the result. */ - TALER_EXCHANGE_RefundResultCallback cb; + TALER_EXCHANGE_RefundCallback cb; /** * Closure for @a cb. @@ -250,7 +250,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t rtransaction_id, const struct TALER_MerchantPrivateKeyP *merchant_priv, - TALER_EXCHANGE_RefundResultCallback cb, + TALER_EXCHANGE_RefundCallback cb, void *cb_cls) { struct TALER_RefundRequestPS rr; @@ -326,7 +326,7 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange, uint64_t rtransaction_id, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantSignatureP *merchant_sig, - TALER_EXCHANGE_RefundResultCallback cb, + TALER_EXCHANGE_RefundCallback cb, void *cb_cls) { struct TALER_EXCHANGE_RefundHandle *rh; diff --git a/src/lib/exchange_api_reserve.c b/src/lib/exchange_api_reserve.c index c0dd66e8f..95a4a90eb 100644 --- a/src/lib/exchange_api_reserve.c +++ b/src/lib/exchange_api_reserve.c @@ -37,7 +37,7 @@ /** * @brief A Withdraw Status Handle */ -struct TALER_EXCHANGE_ReserveStatusHandle +struct TALER_EXCHANGE_ReservesGetHandle { /** @@ -58,7 +58,7 @@ struct TALER_EXCHANGE_ReserveStatusHandle /** * Function to call with the result. */ - TALER_EXCHANGE_ReserveStatusResultCallback cb; + TALER_EXCHANGE_ReservesGetCallback cb; /** * Public key of the reserve we are querying. @@ -495,7 +495,7 @@ free_rhistory (struct TALER_EXCHANGE_ReserveHistory *rhistory, * @return #GNUNET_OK on success */ static int -handle_reserve_status_ok (struct TALER_EXCHANGE_ReserveStatusHandle *rsh, +handle_reserve_status_ok (struct TALER_EXCHANGE_ReservesGetHandle *rsh, const json_t *j) { json_t *history; @@ -575,7 +575,7 @@ handle_reserve_status_ok (struct TALER_EXCHANGE_ReserveStatusHandle *rsh, * Function called when we're done processing the * HTTP /reserve/status request. * - * @param cls the `struct TALER_EXCHANGE_ReserveStatusHandle` + * @param cls the `struct TALER_EXCHANGE_ReservesGetHandle` * @param response_code HTTP response code, 0 on error * @param response parsed JSON result, NULL on error */ @@ -584,7 +584,7 @@ handle_reserve_status_finished (void *cls, long response_code, const void *response) { - struct TALER_EXCHANGE_ReserveStatusHandle *rsh = cls; + struct TALER_EXCHANGE_ReservesGetHandle *rsh = cls; const json_t *j = response; rsh->job = NULL; @@ -629,7 +629,7 @@ handle_reserve_status_finished (void *cls, 0, NULL); rsh->cb = NULL; } - TALER_EXCHANGE_reserve_status_cancel (rsh); + TALER_EXCHANGE_reserves_get_cancel (rsh); } @@ -649,14 +649,14 @@ handle_reserve_status_finished (void *cls, * @return a handle for this request; NULL if the inputs are invalid (i.e. * signatures fail to verify). In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveStatusHandle * -TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_ReservePublicKeyP *reserve_pub, - TALER_EXCHANGE_ReserveStatusResultCallback cb, - void *cb_cls) +struct TALER_EXCHANGE_ReservesGetHandle * +TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_ReservePublicKeyP *reserve_pub, + TALER_EXCHANGE_ReservesGetCallback cb, + void *cb_cls) { - struct TALER_EXCHANGE_ReserveStatusHandle *rsh; + struct TALER_EXCHANGE_ReservesGetHandle *rsh; struct GNUNET_CURL_Context *ctx; CURL *eh; char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 16]; @@ -682,7 +682,7 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange, "/reserves/%s", pub_str); } - rsh = GNUNET_new (struct TALER_EXCHANGE_ReserveStatusHandle); + rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesGetHandle); rsh->exchange = exchange; rsh->cb = cb; rsh->cb_cls = cb_cls; @@ -707,8 +707,8 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange, * @param rsh the reserve status request handle */ void -TALER_EXCHANGE_reserve_status_cancel (struct - TALER_EXCHANGE_ReserveStatusHandle *rsh) +TALER_EXCHANGE_reserves_get_cancel (struct + TALER_EXCHANGE_ReservesGetHandle *rsh) { if (NULL != rsh->job) { @@ -725,7 +725,7 @@ TALER_EXCHANGE_reserve_status_cancel (struct /** * @brief A Withdraw Sign Handle */ -struct TALER_EXCHANGE_ReserveWithdrawHandle +struct TALER_EXCHANGE_WithdrawHandle { /** @@ -752,7 +752,7 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle /** * Function to call with the result. */ - TALER_EXCHANGE_ReserveWithdrawResultCallback cb; + TALER_EXCHANGE_WithdrawCallback cb; /** * Secrets of the planchet. @@ -796,7 +796,7 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors */ static int -reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh, +reserve_withdraw_ok (struct TALER_EXCHANGE_WithdrawHandle *wsh, const json_t *json) { struct GNUNET_CRYPTO_RsaSignature *blind_sig; @@ -855,7 +855,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh, */ static int reserve_withdraw_payment_required (struct - TALER_EXCHANGE_ReserveWithdrawHandle *wsh, + TALER_EXCHANGE_WithdrawHandle *wsh, const json_t *json) { struct TALER_Amount balance; @@ -956,7 +956,7 @@ reserve_withdraw_payment_required (struct * Function called when we're done processing the * HTTP /reserves/$RESERVE_PUB/withdraw request. * - * @param cls the `struct TALER_EXCHANGE_ReserveWithdrawHandle` + * @param cls the `struct TALER_EXCHANGE_WithdrawHandle` * @param response_code HTTP response code, 0 on error * @param response parsed JSON result, NULL on error */ @@ -965,7 +965,7 @@ handle_reserve_withdraw_finished (void *cls, long response_code, const void *response) { - struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh = cls; + struct TALER_EXCHANGE_WithdrawHandle *wsh = cls; const json_t *j = response; wsh->job = NULL; @@ -1031,13 +1031,13 @@ handle_reserve_withdraw_finished (void *cls, j); wsh->cb = NULL; } - TALER_EXCHANGE_reserve_withdraw_cancel (wsh); + TALER_EXCHANGE_withdraw_cancel (wsh); } /** - * Helper function for #TALER_EXCHANGE_reserve_withdraw2() and - * #TALER_EXCHANGE_reserve_withdraw(). + * Helper function for #TALER_EXCHANGE_withdraw2() and + * #TALER_EXCHANGE_withdraw(). * * @param exchange the exchange handle; the exchange must be ready to operate * @param pk kind of coin to create @@ -1052,17 +1052,17 @@ handle_reserve_withdraw_finished (void *cls, * if the inputs are invalid (i.e. denomination key not with this exchange). * In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveWithdrawHandle * +struct TALER_EXCHANGE_WithdrawHandle * reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_EXCHANGE_DenomPublicKey *pk, const struct TALER_ReserveSignatureP *reserve_sig, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_PlanchetSecretsP *ps, const struct TALER_PlanchetDetail *pd, - TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb, + TALER_EXCHANGE_WithdrawCallback res_cb, void *res_cb_cls) { - struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh; + struct TALER_EXCHANGE_WithdrawHandle *wsh; struct GNUNET_CURL_Context *ctx; json_t *withdraw_obj; CURL *eh; @@ -1084,7 +1084,7 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange, "/reserves/%s/withdraw", pub_str); } - wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle); + wsh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle); wsh->exchange = exchange; wsh->cb = res_cb; wsh->cb_cls = res_cb_cls; @@ -1159,21 +1159,21 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange, * if the inputs are invalid (i.e. denomination key not with this exchange). * In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveWithdrawHandle * -TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct - TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_PlanchetSecretsP *ps, - TALER_EXCHANGE_ReserveWithdrawResultCallback - res_cb, - void *res_cb_cls) +struct TALER_EXCHANGE_WithdrawHandle * +TALER_EXCHANGE_withdraw (struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_EXCHANGE_DenomPublicKey *pk, + const struct + TALER_ReservePrivateKeyP *reserve_priv, + const struct TALER_PlanchetSecretsP *ps, + TALER_EXCHANGE_WithdrawCallback + res_cb, + void *res_cb_cls) { struct TALER_Amount amount_with_fee; struct TALER_ReserveSignatureP reserve_sig; struct TALER_WithdrawRequestPS req; struct TALER_PlanchetDetail pd; - struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh; + struct TALER_EXCHANGE_WithdrawHandle *wsh; GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv, &req.reserve_pub.eddsa_pub); @@ -1243,20 +1243,20 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange, * if the inputs are invalid (i.e. denomination key not with this exchange). * In this case, the callback is not called. */ -struct TALER_EXCHANGE_ReserveWithdrawHandle * -TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_EXCHANGE_DenomPublicKey *pk, - const struct - TALER_ReserveSignatureP *reserve_sig, - const struct - TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_PlanchetSecretsP *ps, - TALER_EXCHANGE_ReserveWithdrawResultCallback - res_cb, - void *res_cb_cls) +struct TALER_EXCHANGE_WithdrawHandle * +TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_EXCHANGE_DenomPublicKey *pk, + const struct + TALER_ReserveSignatureP *reserve_sig, + const struct + TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_PlanchetSecretsP *ps, + TALER_EXCHANGE_WithdrawCallback + res_cb, + void *res_cb_cls) { - struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh; + struct TALER_EXCHANGE_WithdrawHandle *wsh; struct TALER_PlanchetDetail pd; if (GNUNET_OK != @@ -1287,9 +1287,9 @@ TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, * @param sign the withdraw sign request handle */ void -TALER_EXCHANGE_reserve_withdraw_cancel (struct - TALER_EXCHANGE_ReserveWithdrawHandle * - sign) +TALER_EXCHANGE_withdraw_cancel (struct + TALER_EXCHANGE_WithdrawHandle * + sign) { if (NULL != sign->job) { diff --git a/src/lib/exchange_api_track_transaction.c b/src/lib/exchange_api_track_transaction.c index 503ceea5b..636b986f9 100644 --- a/src/lib/exchange_api_track_transaction.c +++ b/src/lib/exchange_api_track_transaction.c @@ -35,7 +35,7 @@ /** * @brief A Deposit Wtid Handle */ -struct TALER_EXCHANGE_TrackTransactionHandle +struct TALER_EXCHANGE_DepositGetHandle { /** @@ -62,7 +62,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle /** * Function to call with the result. */ - TALER_EXCHANGE_TrackTransactionCallback cb; + TALER_EXCHANGE_DepositGetCallback cb; /** * Closure for @a cb. @@ -89,7 +89,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle */ static int verify_deposit_wtid_signature_ok (const struct - TALER_EXCHANGE_TrackTransactionHandle *dwh, + TALER_EXCHANGE_DepositGetHandle *dwh, const json_t *json, struct TALER_ExchangePublicKeyP *exchange_pub) { @@ -134,7 +134,7 @@ verify_deposit_wtid_signature_ok (const struct * Function called when we're done processing the * HTTP /track/transaction request. * - * @param cls the `struct TALER_EXCHANGE_TrackTransactionHandle` + * @param cls the `struct TALER_EXCHANGE_DepositGetHandle` * @param response_code HTTP response code, 0 on error * @param response parsed JSON result, NULL on error */ @@ -143,7 +143,7 @@ handle_deposit_wtid_finished (void *cls, long response_code, const void *response) { - struct TALER_EXCHANGE_TrackTransactionHandle *dwh = cls; + struct TALER_EXCHANGE_DepositGetHandle *dwh = cls; const struct TALER_WireTransferIdentifierRawP *wtid = NULL; struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS; const struct TALER_Amount *coin_contribution = NULL; @@ -247,7 +247,7 @@ handle_deposit_wtid_finished (void *cls, wtid, execution_time, coin_contribution); - TALER_EXCHANGE_track_transaction_cancel (dwh); + TALER_EXCHANGE_deposits_get_cancel (dwh); } @@ -264,21 +264,21 @@ handle_deposit_wtid_finished (void *cls, * @param cb_cls closure for @a cb * @return handle to abort request */ -struct TALER_EXCHANGE_TrackTransactionHandle * -TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_MerchantPrivateKeyP *merchant_priv, - const struct GNUNET_HashCode *h_wire, - const struct - GNUNET_HashCode *h_contract_terms, - const struct - TALER_CoinSpendPublicKeyP *coin_pub, - TALER_EXCHANGE_TrackTransactionCallback cb, - void *cb_cls) +struct TALER_EXCHANGE_DepositGetHandle * +TALER_EXCHANGE_deposits_get (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_MerchantPrivateKeyP *merchant_priv, + const struct GNUNET_HashCode *h_wire, + const struct + GNUNET_HashCode *h_contract_terms, + const struct + TALER_CoinSpendPublicKeyP *coin_pub, + TALER_EXCHANGE_DepositGetCallback cb, + void *cb_cls) { struct TALER_DepositTrackPS dtp; struct TALER_MerchantSignatureP merchant_sig; - struct TALER_EXCHANGE_TrackTransactionHandle *dwh; + struct TALER_EXCHANGE_DepositGetHandle *dwh; struct GNUNET_CURL_Context *ctx; CURL *eh; char arg_str[(sizeof (struct TALER_CoinSpendPublicKeyP) @@ -354,7 +354,7 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange, msig_str); } - dwh = GNUNET_new (struct TALER_EXCHANGE_TrackTransactionHandle); + dwh = GNUNET_new (struct TALER_EXCHANGE_DepositGetHandle); dwh->exchange = exchange; dwh->cb = cb; dwh->cb_cls = cb_cls; @@ -384,9 +384,9 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange, * @param dwh the wire deposits request handle */ void -TALER_EXCHANGE_track_transaction_cancel (struct - TALER_EXCHANGE_TrackTransactionHandle * - dwh) +TALER_EXCHANGE_deposits_get_cancel (struct + TALER_EXCHANGE_DepositGetHandle * + dwh) { if (NULL != dwh->job) { diff --git a/src/lib/exchange_api_track_transfer.c b/src/lib/exchange_api_track_transfer.c index 2fdfdde16..c5d484d23 100644 --- a/src/lib/exchange_api_track_transfer.c +++ b/src/lib/exchange_api_track_transfer.c @@ -34,7 +34,7 @@ /** * @brief A /track/transfer Handle */ -struct TALER_EXCHANGE_TrackTransferHandle +struct TALER_EXCHANGE_TransfersGetHandle { /** @@ -55,7 +55,7 @@ struct TALER_EXCHANGE_TrackTransferHandle /** * Function to call with the result. */ - TALER_EXCHANGE_TrackTransferCallback cb; + TALER_EXCHANGE_TransfersGetCallback cb; /** * Closure for @a cb. @@ -81,7 +81,7 @@ struct TALER_EXCHANGE_TrackTransferHandle */ static int check_track_transfer_response_ok (struct - TALER_EXCHANGE_TrackTransferHandle *wdh, + TALER_EXCHANGE_TransfersGetHandle *wdh, const json_t *json) { json_t *details_j; @@ -241,7 +241,7 @@ check_track_transfer_response_ok (struct details); } GNUNET_JSON_parse_free (spec); - TALER_EXCHANGE_track_transfer_cancel (wdh); + TALER_EXCHANGE_transfers_get_cancel (wdh); return GNUNET_OK; } @@ -250,7 +250,7 @@ check_track_transfer_response_ok (struct * Function called when we're done processing the * HTTP /track/transfer request. * - * @param cls the `struct TALER_EXCHANGE_TrackTransferHandle` + * @param cls the `struct TALER_EXCHANGE_TransfersGetHandle` * @param response_code HTTP response code, 0 on error * @param response parsed JSON result, NULL on error */ @@ -259,7 +259,7 @@ handle_track_transfer_finished (void *cls, long response_code, const void *response) { - struct TALER_EXCHANGE_TrackTransferHandle *wdh = cls; + struct TALER_EXCHANGE_TransfersGetHandle *wdh = cls; const json_t *j = response; wdh->job = NULL; @@ -311,7 +311,7 @@ handle_track_transfer_finished (void *cls, NULL, NULL, 0, NULL); - TALER_EXCHANGE_track_transfer_cancel (wdh); + TALER_EXCHANGE_transfers_get_cancel (wdh); } @@ -325,14 +325,14 @@ handle_track_transfer_finished (void *cls, * @param cb_cls closure for @a cb * @return handle to cancel operation */ -struct TALER_EXCHANGE_TrackTransferHandle * -TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange, - const struct - TALER_WireTransferIdentifierRawP *wtid, - TALER_EXCHANGE_TrackTransferCallback cb, - void *cb_cls) +struct TALER_EXCHANGE_TransfersGetHandle * +TALER_EXCHANGE_transfers_get (struct TALER_EXCHANGE_Handle *exchange, + const struct + TALER_WireTransferIdentifierRawP *wtid, + TALER_EXCHANGE_TransfersGetCallback cb, + void *cb_cls) { - struct TALER_EXCHANGE_TrackTransferHandle *wdh; + struct TALER_EXCHANGE_TransfersGetHandle *wdh; struct GNUNET_CURL_Context *ctx; CURL *eh; char arg_str[sizeof (struct TALER_WireTransferIdentifierRawP) * 2 + 32]; @@ -344,7 +344,7 @@ TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange, return NULL; } - wdh = GNUNET_new (struct TALER_EXCHANGE_TrackTransferHandle); + wdh = GNUNET_new (struct TALER_EXCHANGE_TransfersGetHandle); wdh->exchange = exchange; wdh->cb = cb; wdh->cb_cls = cb_cls; @@ -384,8 +384,8 @@ TALER_EXCHANGE_track_transfer (struct TALER_EXCHANGE_Handle *exchange, * @param wdh the wire deposits request handle */ void -TALER_EXCHANGE_track_transfer_cancel (struct - TALER_EXCHANGE_TrackTransferHandle *wdh) +TALER_EXCHANGE_transfers_get_cancel (struct + TALER_EXCHANGE_TransfersGetHandle *wdh) { if (NULL != wdh->job) { diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c index 9d17f5c80..123f77e13 100644 --- a/src/lib/exchange_api_wire.c +++ b/src/lib/exchange_api_wire.c @@ -55,7 +55,7 @@ struct TALER_EXCHANGE_WireHandle /** * Function to call with the result. */ - TALER_EXCHANGE_WireResultCallback cb; + TALER_EXCHANGE_WireCallback cb; /** * Closure for @a cb. @@ -388,7 +388,7 @@ handle_wire_finished (void *cls, */ struct TALER_EXCHANGE_WireHandle * TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange, - TALER_EXCHANGE_WireResultCallback wire_cb, + TALER_EXCHANGE_WireCallback wire_cb, void *wire_cb_cls) { struct TALER_EXCHANGE_WireHandle *wh; diff --git a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c index 6115ceef6..96d0740e1 100644 --- a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c +++ b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c @@ -227,8 +227,8 @@ deposit_confirmation_run (void *cls, &exchange_sig)); keys = TALER_EXCHANGE_get_keys (dcs->is->exchange); GNUNET_assert (NULL != keys); - spk = TALER_EXCHANGE_get_exchange_signing_key_info (keys, - exchange_pub); + spk = TALER_EXCHANGE_get_signing_key_info (keys, + exchange_pub); GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_contract_terms (deposit_cmd, diff --git a/src/testing/testing_api_cmd_status.c b/src/testing/testing_api_cmd_status.c index 690a5b9cd..bb1326456 100644 --- a/src/testing/testing_api_cmd_status.c +++ b/src/testing/testing_api_cmd_status.c @@ -41,7 +41,7 @@ struct StatusState /** * Handle to the "reserve status" operation. */ - struct TALER_EXCHANGE_ReserveStatusHandle *rsh; + struct TALER_EXCHANGE_ReservesGetHandle *rsh; /** * Expected reserve balance. @@ -169,10 +169,10 @@ status_run (void *cls, TALER_TESTING_interpreter_fail (is); return; } - ss->rsh = TALER_EXCHANGE_reserve_status (is->exchange, - reserve_pubp, - &reserve_status_cb, - ss); + ss->rsh = TALER_EXCHANGE_reserves_get (is->exchange, + reserve_pubp, + &reserve_status_cb, + ss); } @@ -195,7 +195,7 @@ status_cleanup (void *cls, "Command %u (%s) did not complete\n", ss->is->ip, cmd->label); - TALER_EXCHANGE_reserve_status_cancel (ss->rsh); + TALER_EXCHANGE_reserves_get_cancel (ss->rsh); ss->rsh = NULL; } GNUNET_free (ss); diff --git a/src/testing/testing_api_cmd_track.c b/src/testing/testing_api_cmd_track.c index 2b7263cda..6ebef6933 100644 --- a/src/testing/testing_api_cmd_track.c +++ b/src/testing/testing_api_cmd_track.c @@ -64,7 +64,7 @@ struct TrackTransactionState /** * Handle to the "track transaction" pending operation. */ - struct TALER_EXCHANGE_TrackTransactionHandle *tth; + struct TALER_EXCHANGE_DepositGetHandle *tth; /** * Interpreter state. @@ -124,7 +124,7 @@ struct TrackTransferState /** * Handle to a pending "track transfer" operation. */ - struct TALER_EXCHANGE_TrackTransferHandle *tth; + struct TALER_EXCHANGE_TransfersGetHandle *tth; /** * Interpreter state. @@ -327,13 +327,13 @@ track_transaction_run (void *cls, return; } - tts->tth = TALER_EXCHANGE_track_transaction (is->exchange, - merchant_priv, - &h_wire_details, - &h_contract_terms, - &coin_pub, - &deposit_wtid_cb, - tts); + tts->tth = TALER_EXCHANGE_deposits_get (is->exchange, + merchant_priv, + &h_wire_details, + &h_contract_terms, + &coin_pub, + &deposit_wtid_cb, + tts); GNUNET_assert (NULL != tts->tth); } @@ -357,7 +357,7 @@ track_transaction_cleanup (void *cls, "Command %u (%s) did not complete\n", tts->is->ip, cmd->label); - TALER_EXCHANGE_track_transaction_cancel (tts->tth); + TALER_EXCHANGE_deposits_get_cancel (tts->tth); tts->tth = NULL; } GNUNET_free (tts); @@ -453,7 +453,7 @@ track_transfer_cleanup (void *cls, "Command %u (%s) did not complete\n", tts->is->ip, cmd->label); - TALER_EXCHANGE_track_transfer_cancel (tts->tth); + TALER_EXCHANGE_transfers_get_cancel (tts->tth); tts->tth = NULL; } GNUNET_free (tts); @@ -709,10 +709,10 @@ track_transfer_run (void *cls, } GNUNET_assert (NULL != wtid_ptr); } - tts->tth = TALER_EXCHANGE_track_transfer (is->exchange, - wtid_ptr, - &track_transfer_cb, - tts); + tts->tth = TALER_EXCHANGE_transfers_get (is->exchange, + wtid_ptr, + &track_transfer_cb, + tts); GNUNET_assert (NULL != tts->tth); } diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 207d11876..964121562 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -80,7 +80,7 @@ struct WithdrawState /** * Withdraw handle (while operation is running). */ - struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh; + struct TALER_EXCHANGE_WithdrawHandle *wsh; /** * Task scheduled to try later. @@ -280,12 +280,12 @@ withdraw_run (void *cls, * would free the old one. */ ws->pk = TALER_EXCHANGE_copy_denomination_key (dpk); } - ws->wsh = TALER_EXCHANGE_reserve_withdraw (is->exchange, - ws->pk, - rp, - &ws->ps, - &reserve_withdraw_cb, - ws); + ws->wsh = TALER_EXCHANGE_withdraw (is->exchange, + ws->pk, + rp, + &ws->ps, + &reserve_withdraw_cb, + ws); if (NULL == ws->wsh) { GNUNET_break (0); @@ -313,7 +313,7 @@ withdraw_cleanup (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Command %s did not complete\n", cmd->label); - TALER_EXCHANGE_reserve_withdraw_cancel (ws->wsh); + TALER_EXCHANGE_withdraw_cancel (ws->wsh); ws->wsh = NULL; } if (NULL != ws->retry_task) -- cgit v1.2.3