diff options
| author | Christian Grothoff <christian@grothoff.org> | 2019-07-22 19:17:02 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2019-07-22 19:17:02 +0200 | 
| commit | 84751de47b862fe13a1477def643f63d0d2d55ac (patch) | |
| tree | 8da3102237f9fb4c6cabcead5047b4bbdd0dad39 /src | |
| parent | a83aa1f70ec66b468c3498251ea55f3ab89f6b0e (diff) | |
integrating refresh payback with standard payback, almost done
Diffstat (limited to 'src')
| -rw-r--r-- | src/exchange/Makefile.am | 1 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd.c | 8 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_payback.c | 185 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_refresh_payback.c | 57 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_refresh_payback.h | 49 | 
5 files changed, 149 insertions, 151 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index 2b5a10e9..b5419a7a 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 734f260b..fe484979 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 2f1a2dde..df79cea2 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 3687d19d..00000000 --- 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 921715c7..00000000 --- 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  | 
