aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exchange/Makefile.am1
-rw-r--r--src/exchange/taler-exchange-httpd.c8
-rw-r--r--src/exchange/taler-exchange-httpd_payback.c185
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_payback.c57
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_payback.h49
5 files changed, 149 insertions, 151 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index 2b5a10e9c..b5419a7a6 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -51,7 +51,6 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_payback.c taler-exchange-httpd_payback.h \
taler-exchange-httpd_refresh_link.c taler-exchange-httpd_refresh_link.h \
taler-exchange-httpd_refresh_melt.c taler-exchange-httpd_refresh_melt.h \
- taler-exchange-httpd_refresh_payback.c taler-exchange-httpd_refresh_payback.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 \
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 734f260ba..fe484979d 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -36,7 +36,6 @@
#include "taler-exchange-httpd_payback.h"
#include "taler-exchange-httpd_refresh_link.h"
#include "taler-exchange-httpd_refresh_melt.h"
-#include "taler-exchange-httpd_refresh_payback.h"
#include "taler-exchange-httpd_refresh_reveal.h"
#include "taler-exchange-httpd_track_transfer.h"
#include "taler-exchange-httpd_track_transaction.h"
@@ -318,13 +317,6 @@ handle_mhd_request (void *cls,
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
- { "/refresh/payback", MHD_HTTP_METHOD_POST, "application/json",
- NULL, 0,
- &TEH_REFRESH_handler_refresh_payback, MHD_HTTP_OK },
- { "/refresh/payback", NULL, "text/plain",
- "Only POST is allowed", 0,
- &TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
-
{ "/track/transfer", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TEH_TRACKING_handler_track_transfer, MHD_HTTP_OK },
diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c
index 2f1a2dde7..df79cea2c 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -44,7 +44,7 @@
*/
static int
reply_payback_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
@@ -59,6 +59,54 @@ reply_payback_unknown (struct MHD_Connection *connection,
*
* @param connection connection to the client
* @param coin_pub coin for which we are processing the payback request
+ * @param old_coin_pub public key of the old coin that will receive the payback
+ * @param amount the amount we will wire back
+ * @param timestamp when did the exchange receive the /payback request
+ * @return MHD result code
+ */
+static int
+reply_payback_refresh_success (struct MHD_Connection *connection,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ const struct TALER_Amount *amount,
+ struct GNUNET_TIME_Absolute timestamp)
+{
+ struct TALER_PaybackRefreshConfirmationPS pc;
+ struct TALER_ExchangePublicKeyP pub;
+ struct TALER_ExchangeSignatureP sig;
+
+ pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK_REFRESH);
+ pc.purpose.size = htonl (sizeof (struct TALER_PaybackRefreshConfirmationPS));
+ pc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
+ TALER_amount_hton (&pc.payback_amount,
+ amount);
+ pc.coin_pub = *coin_pub;
+ pc.old_coin_pub = *old_coin_pub;
+ if (GNUNET_OK !=
+ TEH_KS_sign (&pc.purpose,
+ &pub,
+ &sig))
+ {
+ return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
+ }
+ return TEH_RESPONSE_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o}",
+ "old_coin_pub", GNUNET_JSON_from_data_auto (old_coin_pub),
+ "timestamp", GNUNET_JSON_from_time_abs (timestamp),
+ "amount", TALER_JSON_from_amount (amount),
+ "exchange_sig", GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub", GNUNET_JSON_from_data_auto (&pub));
+}
+
+
+/**
+ * A wallet asked for /payback, return the successful response.
+ *
+ * @param connection connection to the client
+ * @param coin_pub coin for which we are processing the payback request
* @param reserve_pub public key of the reserve that will receive the payback
* @param amount the amount we will wire back
* @param timestamp when did the exchange receive the /payback request
@@ -66,10 +114,10 @@ reply_payback_unknown (struct MHD_Connection *connection,
*/
static int
reply_payback_success (struct MHD_Connection *connection,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Absolute timestamp)
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *amount,
+ struct GNUNET_TIME_Absolute timestamp)
{
struct TALER_PaybackConfirmationPS pc;
struct TALER_ExchangePublicKeyP pub;
@@ -132,11 +180,20 @@ struct PaybackContext
*/
const struct TALER_CoinSpendSignatureP *coin_sig;
- /**
- * Set by #payback_transaction() to the reserve that will
- * receive the payback.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
+ union
+ {
+ /**
+ * Set by #payback_transaction() to the reserve that will
+ * receive the payback, if #refreshed is #GNUNET_NO.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Set by #payback_transaction() to the old coin that will
+ * receive the payback, if #refreshed is #GNUNET_YES.
+ */
+ struct TALER_CoinSpendPublicKeyP old_coin_pub;
+ } target;
/**
* Set by #payback_transaction() to the amount that will be paid back
@@ -149,6 +206,11 @@ struct PaybackContext
*/
struct GNUNET_TIME_Absolute now;
+ /**
+ * #GNUNET_YES if the client claims the coin originated from a refresh.
+ */
+ int refreshed;
+
};
@@ -183,19 +245,42 @@ payback_transaction (void *cls,
/* Check whether a payback is allowed, and if so, to which
reserve / account the money should go */
- qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
- session,
- &pc->h_blind,
- &pc->reserve_pub);
- if (0 > qs)
+ if (pc->refreshed)
{
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ GNUNET_assert (0); // FIXME: not implemented in DB!
+#if 0
+ qs = TEH_plugin->get_old_coin_by_h_blind (TEH_plugin->cls,
+ session,
+ &pc->h_blind,
+ &pc->target.old_coin_pub);
+#endif
+ if (0 > qs)
{
- GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_DB_FETCH_FAILED);
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ {
+ GNUNET_break (0);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_PAYBACK_DB_FETCH_FAILED);
+ }
+ return qs;
+ }
+ }
+ else
+ {
+ qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
+ session,
+ &pc->h_blind,
+ &pc->target.reserve_pub);
+ if (0 > qs)
+ {
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ {
+ GNUNET_break (0);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_PAYBACK_DB_FETCH_FAILED);
+ }
+ return qs;
}
- return qs;
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
@@ -266,15 +351,29 @@ payback_transaction (void *cls,
(void) GNUNET_TIME_round_abs (&pc->now);
/* add coin to list of wire transfers for payback */
- qs = TEH_plugin->insert_payback_request (TEH_plugin->cls,
- session,
- &pc->reserve_pub,
- pc->coin,
- pc->coin_sig,
- pc->coin_bks,
- &pc->amount,
- &pc->h_blind,
- pc->now);
+ if (pc->refreshed)
+ {
+ qs = TEH_plugin->insert_payback_refresh_request (TEH_plugin->cls,
+ session,
+ pc->coin,
+ pc->coin_sig,
+ pc->coin_bks,
+ &pc->amount,
+ &pc->h_blind,
+ pc->now);
+ }
+ else
+ {
+ qs = TEH_plugin->insert_payback_request (TEH_plugin->cls,
+ session,
+ &pc->target.reserve_pub,
+ pc->coin,
+ pc->coin_sig,
+ pc->coin_bks,
+ &pc->amount,
+ &pc->h_blind,
+ pc->now);
+ }
if (0 > qs)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
@@ -300,13 +399,15 @@ payback_transaction (void *cls,
* @param coin information about the coin
* @param coin_bks blinding data of the coin (to be checked)
* @param coin_sig signature of the coin
+ * @param refreshed #GNUNET_YES if the coin was refreshed
* @return MHD result code
*/
static int
verify_and_execute_payback (struct MHD_Connection *connection,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationBlindingKeyP *coin_bks,
- const struct TALER_CoinSpendSignatureP *coin_sig)
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ int refreshed)
{
struct PaybackContext pc;
struct TEH_KS_StateHandle *key_state;
@@ -413,6 +514,7 @@ verify_and_execute_payback (struct MHD_Connection *connection,
pc.coin_sig = coin_sig;
pc.coin_bks = coin_bks;
pc.coin = coin;
+ pc.refreshed = refreshed;
{
int mhd_ret;
@@ -424,11 +526,17 @@ verify_and_execute_payback (struct MHD_Connection *connection,
&pc))
return mhd_ret;
}
- return reply_payback_success (connection,
- &coin->coin_pub,
- &pc.reserve_pub,
- &pc.amount,
- pc.now);
+ return (refreshed)
+ ? reply_payback_refresh_success (connection,
+ &coin->coin_pub,
+ &pc.target.old_coin_pub,
+ &pc.amount,
+ pc.now)
+ : reply_payback_success (connection,
+ &coin->coin_pub,
+ &pc.target.reserve_pub,
+ &pc.amount,
+ pc.now);
}
@@ -458,6 +566,7 @@ TEH_PAYBACK_handler_payback (struct TEH_RequestHandler *rh,
struct TALER_CoinPublicInfo coin;
struct TALER_DenominationBlindingKeyP coin_bks;
struct TALER_CoinSpendSignatureP coin_sig;
+ int refreshed = GNUNET_NO;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
&coin.denom_pub_hash),
@@ -469,6 +578,9 @@ TEH_PAYBACK_handler_payback (struct TEH_RequestHandler *rh,
&coin_bks),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
+ GNUNET_JSON_spec_mark_optional
+ (GNUNET_JSON_spec_boolean ("refreshed",
+ &refreshed)),
GNUNET_JSON_spec_end ()
};
@@ -492,7 +604,8 @@ TEH_PAYBACK_handler_payback (struct TEH_RequestHandler *rh,
res = verify_and_execute_payback (connection,
&coin,
&coin_bks,
- &coin_sig);
+ &coin_sig,
+ refreshed);
GNUNET_JSON_parse_free (spec);
return res;
}
diff --git a/src/exchange/taler-exchange-httpd_refresh_payback.c b/src/exchange/taler-exchange-httpd_refresh_payback.c
deleted file mode 100644
index 3687d19d8..000000000
--- a/src/exchange/taler-exchange-httpd_refresh_payback.c
+++ /dev/null
@@ -1,57 +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 <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_refresh_link.c
- * @brief Handle /refresh/link requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include "taler-exchange-httpd_parsing.h"
-#include "taler-exchange-httpd_mhd.h"
-#include "taler-exchange-httpd_refresh_payback.h"
-#include "taler-exchange-httpd_responses.h"
-#include "taler-exchange-httpd_keystate.h"
-
-
-/**
- * Handle a "/refresh/payback" request. Parses the request into the JSON
- * components and then processes the request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TEH_REFRESH_handler_refresh_payback (struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- GNUNET_break (0);
- return MHD_NO;
-}
-
-
-/* end of taler-exchange-httpd_refresh_payback.c */
diff --git a/src/exchange/taler-exchange-httpd_refresh_payback.h b/src/exchange/taler-exchange-httpd_refresh_payback.h
deleted file mode 100644
index 921715c76..000000000
--- a/src/exchange/taler-exchange-httpd_refresh_payback.h
+++ /dev/null
@@ -1,49 +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 <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_refresh_payback.h
- * @brief Handle /refresh/payback requests
- * @author Florian Dold
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_REFRESH_PAYBACK_H
-#define TALER_EXCHANGE_HTTPD_REFRESH_PAYBACK_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-
-/**
- * Handle a "/refresh/payback" request. Parses the request into the JSON
- * components and then processes the request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TEH_REFRESH_handler_refresh_payback (struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-#endif