aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-09-14 00:48:43 +0200
committerChristian Grothoff <christian@grothoff.org>2024-09-14 00:48:43 +0200
commite2354ce622ea3ba015ece7607ee01754fd135f78 (patch)
treed664f8594a5b7be70fd0d6f7e961a09fca68c86a
parent6191cf20fe3b1c0154c1b972a5465361ee744d3a (diff)
return 400 if wallet uses untrusted exchange base URL; towards fixing #9183
-rw-r--r--src/backend/taler-merchant-httpd_exchanges.c50
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-abort.c5
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c14
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-refund.c8
-rw-r--r--src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c6
-rw-r--r--src/backend/taler-merchant-kyccheck.c17
-rw-r--r--src/testing/test_kyc_api.c17
7 files changed, 80 insertions, 37 deletions
diff --git a/src/backend/taler-merchant-httpd_exchanges.c b/src/backend/taler-merchant-httpd_exchanges.c
index 26c2f5cd..f5cefc48 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -35,7 +35,7 @@
* Threshold after which exponential backoff should not increase.
*/
#define RETRY_BACKOFF_THRESHOLD GNUNET_TIME_relative_multiply ( \
- GNUNET_TIME_UNIT_SECONDS, 60)
+ GNUNET_TIME_UNIT_SECONDS, 60)
/**
* This is how long /keys long-polls for, so we should
@@ -43,7 +43,7 @@
* answer. See exchange_api_handle.c.
*/
#define LONG_POLL_THRESHOLD GNUNET_TIME_relative_multiply ( \
- GNUNET_TIME_UNIT_SECONDS, 120)
+ GNUNET_TIME_UNIT_SECONDS, 120)
/**
@@ -248,20 +248,13 @@ TMH_EXCHANGES_get_currency (
static struct TMH_Exchange *
lookup_exchange (const char *exchange_url)
{
- struct TMH_Exchange *exchange;
-
- for (exchange = exchange_head;
+ for (struct TMH_Exchange *exchange = exchange_head;
NULL != exchange;
exchange = exchange->next)
if (0 == strcmp (exchange->url,
exchange_url))
return exchange;
- exchange = GNUNET_new (struct TMH_Exchange);
- exchange->url = GNUNET_strdup (exchange_url);
- GNUNET_CONTAINER_DLL_insert (exchange_head,
- exchange_tail,
- exchange);
- return exchange;
+ return NULL;
}
@@ -476,6 +469,20 @@ TMH_EXCHANGES_keys4exchange (
"Trying to find chosen exchange `%s'\n",
chosen_exchange);
exchange = lookup_exchange (chosen_exchange);
+ if (NULL == exchange)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Exchange `%s' not configured\n",
+ chosen_exchange);
+ return NULL;
+ }
+ if (! exchange->trusted)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Exchange `%s' not trusted\n",
+ chosen_exchange);
+ return NULL;
+ }
fo = GNUNET_new (struct TMH_EXCHANGES_KeysOperation);
fo->fc = fc;
fo->fc_cls = fc_cls;
@@ -972,6 +979,16 @@ accept_exchanges (void *cls,
"EXCHANGE_BASE_URL");
return;
}
+ exchange = lookup_exchange (url);
+ if (NULL != exchange)
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "EXCHANGE_BASE_URL",
+ "same base URL specified again");
+ GNUNET_free (url);
+ return;
+ }
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
@@ -984,9 +1001,12 @@ accept_exchanges (void *cls,
GNUNET_free (url);
return;
}
- exchange = lookup_exchange (url);
- GNUNET_free (url);
+ exchange = GNUNET_new (struct TMH_Exchange);
+ exchange->url = url;
exchange->currency = currency;
+ GNUNET_CONTAINER_DLL_insert (exchange_head,
+ exchange_tail,
+ exchange);
if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
@@ -1067,7 +1087,9 @@ update_exchange_keys (void *cls,
"Received keys change notification: reload `%s'\n",
url);
exchange = lookup_exchange (url);
- reload_exchange_keys (exchange);
+ GNUNET_break (NULL != exchange);
+ if (NULL != exchange)
+ reload_exchange_keys (exchange);
}
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
index 3dbb6fa8..80c6930b 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
@@ -593,11 +593,12 @@ find_next_exchange (struct AbortContext *ac)
ac);
if (NULL == ac->fo)
{
+ /* strange, should have happened on pay! */
GNUNET_break (0);
resume_abort_with_error (ac,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED,
- "Failed to lookup exchange by URL");
+ TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNTRUSTED,
+ ac->current_exchange);
return;
}
return;
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 555e2959..e6097a50 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -1520,10 +1520,10 @@ force_keys (struct ExchangeGroup *eg)
eg);
if (NULL == eg->fo)
{
- GNUNET_break (0);
+ GNUNET_break_op (0);
resume_pay_with_error (pc,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
- "Failed to lookup exchange by URL");
+ TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNTRUSTED,
+ eg->exchange_url);
return;
}
pc->pending_at_eg++;
@@ -1611,13 +1611,13 @@ phase_batch_deposits (struct PayContext *pc)
eg);
if (NULL == eg->fo)
{
- GNUNET_break (0);
+ GNUNET_break_op (0);
pay_end (pc,
TALER_MHD_reply_with_error (
pc->connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
- "Failed to lookup exchange by URL"));
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNTRUSTED,
+ eg->exchange_url));
return;
}
pc->pending_at_eg++;
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
index 5fd81bef..57e3ebe5 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-refund.c
@@ -711,6 +711,14 @@ TMH_post_orders_ID_refund (const struct TMH_RequestHandler *rh,
false,
&exchange_found_cb,
cr);
+ if (NULL == cr->fo)
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNTRUSTED,
+ cr->exchange_url);
+ }
}
break;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c b/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c
index 33be692d..cc47794d 100644
--- a/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c
+++ b/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c
@@ -820,6 +820,12 @@ kyc_status_cb (
false,
&kyc_with_exchange,
ekr);
+ if (NULL == ekr->fo)
+ {
+ GNUNET_break (0);
+ ekr_finished (ekr);
+ return;
+ }
return;
}
ekr->access_token = *access_token;
diff --git a/src/backend/taler-merchant-kyccheck.c b/src/backend/taler-merchant-kyccheck.c
index e97e2702..73307052 100644
--- a/src/backend/taler-merchant-kyccheck.c
+++ b/src/backend/taler-merchant-kyccheck.c
@@ -467,6 +467,8 @@ exchange_check_cb (
struct Inquiry *i = cls;
bool progress = false;
+ if (! i->not_first_time)
+ progress = true;
i->kyc = NULL;
i->last_http_status = ks->hr.http_status;
i->last_ec = ks->hr.ec;
@@ -526,8 +528,9 @@ exchange_check_cb (
/* Forbidden => KYC auth must be wrong */
i->auth_ok = false;
/* Start with long-polling */
- i->due = GNUNET_TIME_absolute_max (i->last_kyc_check.abs_time,
- i->timeout);
+ if (! progress)
+ i->due = GNUNET_TIME_absolute_max (i->last_kyc_check.abs_time,
+ i->timeout);
i->backoff = GNUNET_TIME_UNIT_ZERO;
break;
case MHD_HTTP_NOT_FOUND: /* account unknown */
@@ -541,8 +544,9 @@ exchange_check_cb (
json_decref (i->jlimits);
i->jlimits = NULL;
/* Start immediately with Long-polling */
- i->due = GNUNET_TIME_absolute_max (i->last_kyc_check.abs_time,
- i->timeout);
+ if (! progress)
+ i->due = GNUNET_TIME_absolute_max (i->last_kyc_check.abs_time,
+ i->timeout);
i->backoff = GNUNET_TIME_UNIT_ZERO;
break;
case MHD_HTTP_CONFLICT: /* no account_pub known */
@@ -550,8 +554,9 @@ exchange_check_cb (
/* Conflict => KYC auth wire transfer missing! */
i->auth_ok = false;
/* Start immediately with Long-polling */
- i->due = GNUNET_TIME_absolute_max (i->last_kyc_check.abs_time,
- i->timeout);
+ if (! progress)
+ i->due = GNUNET_TIME_absolute_max (i->last_kyc_check.abs_time,
+ i->timeout);
i->backoff = GNUNET_TIME_UNIT_ZERO;
break;
default:
diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c
index 5a42439b..a60f965a 100644
--- a/src/testing/test_kyc_api.c
+++ b/src/testing/test_kyc_api.c
@@ -101,9 +101,9 @@ static char *merchant_url_i1a;
* @param label label to use for the command.
*/
#define CMD_EXEC_AGGREGATOR(label) \
- TALER_TESTING_cmd_exec_aggregator_with_kyc (label "-aggregator", \
- CONFIG_FILE), \
- TALER_TESTING_cmd_exec_transfer (label "-transfer", CONFIG_FILE)
+ TALER_TESTING_cmd_exec_aggregator_with_kyc (label "-aggregator", \
+ CONFIG_FILE), \
+ TALER_TESTING_cmd_exec_transfer (label "-transfer", CONFIG_FILE)
/**
* Execute the taler-exchange-wirewatch command with
@@ -112,10 +112,10 @@ static char *merchant_url_i1a;
* @param label label to use for the command.
*/
#define CMD_EXEC_WIREWATCH(label) \
- TALER_TESTING_cmd_exec_wirewatch2 ( \
- label, \
- CONFIG_FILE, \
- "exchange-account-exchange")
+ TALER_TESTING_cmd_exec_wirewatch2 ( \
+ label, \
+ CONFIG_FILE, \
+ "exchange-account-exchange")
/**
@@ -241,7 +241,7 @@ run (void *cls,
NULL,
EXCHANGE_URL,
TALER_EXCHANGE_KLPT_NONE,
- MHD_HTTP_NO_CONTENT,
+ MHD_HTTP_OK,
true),
/* now we get the legi UUID by running taler-merchant-depositcheck */
TALER_TESTING_cmd_depositcheck (
@@ -262,6 +262,7 @@ run (void *cls,
CMD_EXEC_WIREWATCH (
"import-kyc-account-withdraw"),
/* Now we should get a status of pending */
+ // FIXME: currently runs into timeout!
TALER_TESTING_cmd_merchant_kyc_get (
"kyc-pending",
merchant_url,