gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: fix report when same exchange UR


From: gnunet
Subject: [taler-merchant] branch master updated: fix report when same exchange URL is configured in multiple configuration sections
Date: Tue, 19 Sep 2023 17:07:39 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 73b8b9e9 fix report when same exchange URL is configured in multiple 
configuration sections
73b8b9e9 is described below

commit 73b8b9e975e0ce0be169a669a06f436223bb2c9d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Sep 19 17:07:08 2023 +0200

    fix report when same exchange URL is configured in multiple configuration 
sections
---
 src/backend/taler-merchant-httpd_exchanges.c  |  12 +-
 src/lib/merchant_api_post_order_pay.c         | 284 +-------------------------
 src/testing/testing_api_cmd_delete_template.c |   9 +-
 3 files changed, 18 insertions(+), 287 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_exchanges.c 
b/src/backend/taler-merchant-httpd_exchanges.c
index 78b4eea6..22eb0f40 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -1276,6 +1276,8 @@ accept_exchanges (void *cls,
   struct TMH_Exchange *exchange;
   char *currency;
 
+  if (GNUNET_SYSERR == trusted_exchange_count)
+    return;
   if (0 != strncasecmp (section,
                         "merchant-exchange-",
                         strlen ("merchant-exchange-")))
@@ -1348,7 +1350,15 @@ accept_exchanges (void *cls,
               "Setup exchange %s as %s\n",
               exchange->url,
               exchange->trusted ? "trusted" : "untrusted");
-  GNUNET_assert (NULL == exchange->retry_task);
+  if (NULL != exchange->retry_task)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Exchange at `%s' configured in multiple configuration 
sections (see `%s')!\n",
+                exchange->url,
+                section);
+    trusted_exchange_count = GNUNET_SYSERR;
+    return;
+  }
   exchange->retry_task
     = GNUNET_SCHEDULER_add_now (&retry_exchange,
                                 exchange);
diff --git a/src/lib/merchant_api_post_order_pay.c 
b/src/lib/merchant_api_post_order_pay.c
index fc2e9a29..5a5c1631 100644
--- a/src/lib/merchant_api_post_order_pay.c
+++ b/src/lib/merchant_api_post_order_pay.c
@@ -108,12 +108,6 @@ struct TALER_MERCHANT_OrderPayHandle
    */
   json_t *error_history;
 
-  /**
-   * Handle to the exchange that issued a problematic
-   * coin (if any).
-   */
-  struct TALER_EXCHANGE_GetKeysHandle *exchange;
-
   /**
    * Number of @e coins we are paying with.
    */
@@ -128,254 +122,6 @@ struct TALER_MERCHANT_OrderPayHandle
 };
 
 
-/**
- * We got a 409 response back from the exchange (or the merchant).
- * Now we need to check the provided cryptographic proof that the
- * coin was actually already spent!
- *
- * @param oph operation handle
- * @param keys key data from the exchange
- * @return #GNUNET_OK if conflict is valid
- */
-static enum GNUNET_GenericReturnValue
-check_conflict (struct TALER_MERCHANT_OrderPayHandle *oph,
-                const struct TALER_EXCHANGE_Keys *keys)
-{
-  struct TALER_Amount spent;
-  struct TALER_Amount spent_plus_contrib;
-  struct TALER_DenominationHashP h_denom_pub_pc;
-  const struct TALER_EXCHANGE_DenomPublicKey *dpk;
-
-  TALER_denom_pub_hash (&oph->error_pc->denom_pub,
-                        &h_denom_pub_pc);
-  dpk = TALER_EXCHANGE_get_denomination_key_by_hash (
-    keys,
-    &h_denom_pub_pc);
-  if (GNUNET_OK !=
-      TALER_EXCHANGE_verify_coin_history (dpk,
-                                          &oph->error_pc->coin_pub,
-                                          oph->error_history,
-                                          &spent))
-  {
-    /* Exchange's history fails to verify */
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  if (0 >
-      TALER_amount_add (&spent_plus_contrib,
-                        &spent,
-                        &oph->error_pc->amount_with_fee))
-  {
-    /* We got an integer overflow? Bad application! */
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (-1 != TALER_amount_cmp (&oph->error_pc->denom_value,
-                              &spent_plus_contrib))
-  {
-    /* according to our calculations, the transaction should
-       have still worked, AND we did not get any proof of
-       coin public key re-use; hence: exchange error! */
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Accepting proof of double-spending (or coin public key 
re-use)\n");
-  return GNUNET_OK;
-}
-
-
-/**
- * We got the fee structure from the exchange. Now
- * validate the conflict error.
- *
- * @param cls a `struct TALER_MERCHANT_OrderPayHandle`
- * @param kr reply from the exchange
- * @param keys keys of the exchange
- */
-static void
-cert_cb (void *cls,
-         const struct TALER_EXCHANGE_KeysResponse *kr,
-         struct TALER_EXCHANGE_Keys *keys)
-{
-  struct TALER_MERCHANT_OrderPayHandle *oph = cls;
-  const struct TALER_EXCHANGE_HttpResponse *ehr = &kr->hr;
-
-  oph->exchange = NULL;
-  if ( (MHD_HTTP_OK != ehr->http_status) ||
-       (NULL == kr->details.ok.keys) ||
-       (NULL == keys) )
-  {
-    struct TALER_MERCHANT_PayResponse pr = {
-      .hr.http_status = MHD_HTTP_CONFLICT,
-      .hr.exchange_http_status = ehr->http_status,
-      .hr.ec = TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
-      .hr.reply = oph->full_reply,
-      .hr.exchange_reply = ehr->reply,
-      .hr.hint = "failed to download /keys from the exchange"
-    };
-
-    oph->pay_cb (oph->pay_cb_cls,
-                 &pr);
-    TALER_MERCHANT_order_pay_cancel (oph);
-    return;
-  }
-  if (TALER_EXCHANGE_VC_INCOMPATIBLE & kr->details.ok.compat)
-  {
-    struct TALER_MERCHANT_PayResponse pr = {
-      .hr.http_status = MHD_HTTP_CONFLICT,
-      .hr.exchange_http_status = 0,
-      .hr.ec = TALER_EC_WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE,
-      .hr.reply = oph->full_reply,
-      .hr.exchange_reply = ehr->reply,
-      .hr.hint = "could not check error: incompatible exchange version"
-    };
-
-    oph->pay_cb (oph->pay_cb_cls,
-                 &pr);
-    TALER_MERCHANT_order_pay_cancel (oph);
-    TALER_EXCHANGE_keys_decref (keys);
-    return;
-  }
-
-  if (GNUNET_OK !=
-      check_conflict (oph,
-                      kr->details.ok.keys))
-  {
-    struct TALER_MERCHANT_PayResponse pr = {
-      .hr.http_status = 0,
-      .hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE,
-      .hr.reply = oph->full_reply
-    };
-
-    oph->pay_cb (oph->pay_cb_cls,
-                 &pr);
-    TALER_MERCHANT_order_pay_cancel (oph);
-    TALER_EXCHANGE_keys_decref (keys);
-    return;
-  }
-
-  {
-    struct TALER_MERCHANT_PayResponse pr = {
-      .hr.http_status = MHD_HTTP_CONFLICT,
-      .hr.ec = TALER_JSON_get_error_code (oph->full_reply),
-      .hr.reply = oph->full_reply
-    };
-
-    oph->pay_cb (oph->pay_cb_cls,
-                 &pr);
-    TALER_MERCHANT_order_pay_cancel (oph);
-    TALER_EXCHANGE_keys_decref (keys);
-  }
-}
-
-
-/**
- * We got a 409 response back from the exchange (or the merchant).
- * Now we need to check the provided cryptograophic proof that the
- * coin was actually already spent!
- *
- * @param[in,out] oph handle of the original pay operation
- * @param[in,out] pr response to modify if #GNUNET_OK is returned
- * @param json cryptograophic proof returned by the
- *        exchange/merchant
- * @return #GNUNET_OK if proof checks out,
- *         #GNUNET_SYSERR if it is wrong,
- *         #GNUNET_NO if checking continues asynchronously
- */
-static enum GNUNET_GenericReturnValue
-parse_conflict (struct TALER_MERCHANT_OrderPayHandle *oph,
-                struct TALER_MERCHANT_PayResponse *pr,
-                const json_t *json)
-{
-  const json_t *ereply;
-  const char *exchange_url;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_object_const ("exchange_reply",
-                                   &ereply),
-    GNUNET_JSON_spec_string ("exchange_url",
-                             &exchange_url),
-    GNUNET_JSON_spec_end ()
-  };
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-  struct GNUNET_JSON_Specification hspec[] = {
-    GNUNET_JSON_spec_json ("history",
-                           &oph->error_history),
-    GNUNET_JSON_spec_fixed_auto ("coin_pub",
-                                 &coin_pub),
-    GNUNET_JSON_spec_end ()
-  };
-  enum TALER_ErrorCode ec = TALER_JSON_get_error_code (json);
-
-  switch (ec)
-  {
-  case TALER_EC_GENERIC_CURRENCY_MISMATCH:
-    /* no proof to check, still very strange, as we
-       should have checked that the currency matches */
-    GNUNET_break_op (0);
-    TALER_MERCHANT_parse_error_details_ (json,
-                                         MHD_HTTP_CONFLICT,
-                                         &pr->hr);
-    return GNUNET_OK;
-  case TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_ALREADY_PAID:
-    /* We can only be happy and accept the result;
-       FIXME: parse the refunds... */
-    TALER_MERCHANT_parse_error_details_ (json,
-                                         MHD_HTTP_CONFLICT,
-                                         &pr->hr);
-    return GNUNET_OK;
-  case TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS:
-    /* main case, handled below */
-    break;
-  default:
-    GNUNET_break_op (0);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected error code %d: %s\n",
-                ec,
-                TALER_ErrorCode_get_hint (ec));
-    return GNUNET_SYSERR;
-  }
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (json,
-                         spec,
-                         NULL, NULL))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (ereply,
-                         hspec,
-                         NULL, NULL))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-
-  for (unsigned int i = 0; i<oph->num_coins; i++)
-  {
-    if (0 ==
-        GNUNET_memcmp (&oph->coins[i].coin_pub,
-                       &coin_pub))
-    {
-      oph->error_pc = &oph->coins[i];
-      oph->full_reply = json_incref ((json_t *) json);
-      oph->exchange = TALER_EXCHANGE_get_keys (oph->ctx,
-                                               oph->error_pc->exchange_url,
-                                               NULL,
-                                               &cert_cb,
-                                               oph);
-      return GNUNET_NO;
-    }
-  }
-  GNUNET_break_op (0); /* complaint is not about any of the coins
-                          that we actually paid with... */
-  GNUNET_JSON_parse_free (hspec);
-  return GNUNET_SYSERR;
-}
-
-
 /**
  * Function called when we're done processing the
  * HTTP /pay request.
@@ -486,27 +232,10 @@ handle_pay_finished (void *cls,
        Pass on to application. */
     break;
   case MHD_HTTP_CONFLICT:
-    {
-      enum GNUNET_GenericReturnValue ret;
-
-      ret = parse_conflict (oph,
-                            &pr,
-                            json);
-      switch (ret)
-      {
-      case GNUNET_OK:
-        /* continued below, 'pr' was modified */
-        break;
-      case GNUNET_NO:
-        /* handled asynchronously! */
-        return; /* ! */
-      case GNUNET_SYSERR:
-        GNUNET_break_op (0);
-        pr.hr.http_status = 0;
-        break;
-      }
-      break;
-    }
+    TALER_MERCHANT_parse_error_details_ (json,
+                                         MHD_HTTP_CONFLICT,
+                                         &pr.hr);
+    break;
   case MHD_HTTP_GONE:
     TALER_MERCHANT_parse_error_details_ (json,
                                          response_code,
@@ -830,11 +559,6 @@ TALER_MERCHANT_order_pay_cancel (struct 
TALER_MERCHANT_OrderPayHandle *oph)
     GNUNET_CURL_job_cancel (oph->job);
     oph->job = NULL;
   }
-  if (NULL != oph->exchange)
-  {
-    TALER_EXCHANGE_get_keys_cancel (oph->exchange);
-    oph->exchange = NULL;
-  }
   TALER_curl_easy_post_finished (&oph->post_ctx);
   json_decref (oph->error_history);
   json_decref (oph->full_reply);
diff --git a/src/testing/testing_api_cmd_delete_template.c 
b/src/testing/testing_api_cmd_delete_template.c
index 95259640..a2c7feeb 100644
--- a/src/testing/testing_api_cmd_delete_template.c
+++ b/src/testing/testing_api_cmd_delete_template.c
@@ -77,12 +77,9 @@ delete_template_cb (void *cls,
   dis->tdh = NULL;
   if (dis->http_status != hr->http_status)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected response code %u (%d) to command %s\n",
-                hr->http_status,
-                (int) hr->ec,
-                TALER_TESTING_interpreter_get_current_label (dis->is));
-    TALER_TESTING_interpreter_fail (dis->is);
+    TALER_TESTING_unexpected_status (dis->is,
+                                     hr->http_status,
+                                     dis->http_status);
     return;
   }
   switch (hr->http_status)

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]