diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-09-14 00:48:43 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-09-14 00:48:43 +0200 |
commit | e2354ce622ea3ba015ece7607ee01754fd135f78 (patch) | |
tree | d664f8594a5b7be70fd0d6f7e961a09fca68c86a | |
parent | 6191cf20fe3b1c0154c1b972a5465361ee744d3a (diff) |
return 400 if wallet uses untrusted exchange base URL; towards fixing #9183
-rw-r--r-- | src/backend/taler-merchant-httpd_exchanges.c | 50 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-abort.c | 5 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 14 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-refund.c | 8 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c | 6 | ||||
-rw-r--r-- | src/backend/taler-merchant-kyccheck.c | 17 | ||||
-rw-r--r-- | src/testing/test_kyc_api.c | 17 |
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, |