aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-09-08 12:25:41 +0200
committerChristian Grothoff <christian@grothoff.org>2024-09-08 12:25:47 +0200
commit9b11a986f0e85eeec594da346f0b5e364c6b33ec (patch)
tree5a097e3dbdc2f4b665a237f35b50adcb6b2505c3
parent1f935754bdf37f8eae5bce85283e3b3dad7eb128 (diff)
actually rely upon taler-merchant-exchangekeyupdate in taler-merchant-httpd
-rw-r--r--src/backend/taler-merchant-exchangekeyupdate.c8
-rw-r--r--src/backend/taler-merchant-httpd_exchanges.c703
-rw-r--r--src/backend/taler-merchant-kyccheck.c2
-rwxr-xr-xsrc/testing/test_merchant_instance_auth.sh1
4 files changed, 146 insertions, 568 deletions
diff --git a/src/backend/taler-merchant-exchangekeyupdate.c b/src/backend/taler-merchant-exchangekeyupdate.c
index 4790953a..07d01d11 100644
--- a/src/backend/taler-merchant-exchangekeyupdate.c
+++ b/src/backend/taler-merchant-exchangekeyupdate.c
@@ -494,10 +494,6 @@ cert_cb (
struct GNUNET_TIME_Absolute n;
e->conn = NULL;
- /* limit retry */
- e->first_retry
- = GNUNET_TIME_relative_to_absolute (
- EXCHANGE_MAXFREQ);
switch (kr->hr.http_status)
{
case MHD_HTTP_OK:
@@ -526,6 +522,10 @@ cert_cb (
e->keys = TALER_EXCHANGE_keys_incref (keys);
/* Reset back-off */
e->retry_delay = EXCHANGE_MAXFREQ;
+ /* limit retry */
+ e->first_retry
+ = GNUNET_TIME_relative_to_absolute (
+ EXCHANGE_MAXFREQ);
/* Limit by expiration */
n = GNUNET_TIME_absolute_max (e->first_retry,
keys->key_data_expiration.abs_time);
diff --git a/src/backend/taler-merchant-httpd_exchanges.c b/src/backend/taler-merchant-httpd_exchanges.c
index 6bcbd5c8..d1397870 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2014-2023 Taler Systems SA
+ (C) 2014-2024 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
@@ -243,12 +243,7 @@ struct TMH_Exchange
char *currency;
/**
- * A connection to this exchange
- */
- struct TALER_EXCHANGE_GetKeysHandle *conn;
-
- /**
- * The keys of this exchange
+ * The keys of this exchange.
*/
struct TALER_EXCHANGE_Keys *keys;
@@ -263,70 +258,24 @@ struct TMH_Exchange
struct FeesByWireMethod *wire_fees_tail;
/**
- * Master public key of the exchange.
+ * Task to retry downloading /keys again.
*/
- struct TALER_MasterPublicKeyP master_pub;
+ struct GNUNET_SCHEDULER_Task *retry_task;
/**
- * How soon can may we, at the earliest, re-download /keys?
+ * When are we willing to force downloading again?
*/
struct GNUNET_TIME_Absolute first_retry;
/**
- * How long should we wait between the next retry?
+ * Current exponential back-off for @e retry_task.
*/
struct GNUNET_TIME_Relative retry_delay;
/**
- * How long should we wait between the next retry for /wire?
- */
- struct GNUNET_TIME_Relative wire_retry_delay;
-
- /**
- * Task where we retry fetching /keys from the exchange.
- */
- struct GNUNET_SCHEDULER_Task *retry_task;
-
- /**
- * What state is this exchange in?
+ * Master public key of the exchange.
*/
- enum
- {
-
- /**
- * Downloading /keys failed.
- */
- ESTATE_FAILED = -1,
-
- /**
- * Nothing was ever done.
- */
- ESTATE_INIT = 0,
-
- /**
- * We are actively downloading /keys for the first time.
- */
- ESTATE_DOWNLOADING_FIRST = 1,
-
- /**
- * We finished downloading /keys and the exchange is
- * ready.
- */
- ESTATE_DOWNLOADED = 2,
-
- /**
- * We are downloading /keys again after a previous
- * success.
- */
- ESTATE_REDOWNLOADING_SUCCESS = 3,
-
- /**
- * We are downloading /keys again after a previous
- * failure.
- */
- ESTATE_REDOWNLOADING_FAILURE = 4
-
- } state;
+ struct TALER_MasterPublicKeyP master_pub;
/**
* true if this exchange is from our configuration and
@@ -446,7 +395,6 @@ static struct TMH_Exchange *
lookup_exchange (const char *exchange_url)
{
struct TMH_Exchange *exchange;
- enum GNUNET_DB_QueryStatus qs;
for (exchange = exchange_head;
NULL != exchange;
@@ -459,16 +407,6 @@ lookup_exchange (const char *exchange_url)
GNUNET_CONTAINER_DLL_insert (exchange_head,
exchange_tail,
exchange);
- qs = TMH_db->select_exchange_keys (TMH_db->cls,
- exchange->url,
- &exchange->keys);
- GNUNET_break (qs >= 0);
- if (qs > 0)
- exchange->state = ESTATE_DOWNLOADED;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "The exchange `%s' is new (%d)\n",
- exchange_url,
- exchange->state);
return exchange;
}
@@ -539,21 +477,6 @@ set_exchange_accounts (
/**
- * Function called with information about who is auditing
- * a particular exchange and what key the exchange is using.
- *
- * @param cls closure, will be `struct TMH_Exchange`
- * @param kr response details
- * @param[in] keys keys object returned
- */
-static void
-keys_mgmt_cb (
- void *cls,
- const struct TALER_EXCHANGE_KeysResponse *kr,
- struct TALER_EXCHANGE_Keys *keys);
-
-
-/**
* Check if we have any remaining pending requests for the
* given @a exchange, and if we have the required data, call
* the callback.
@@ -606,9 +529,8 @@ process_find_operations (struct TMH_Exchange *exchange)
kon = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Processing find operations for `%s' (%d)\n",
- exchange->url,
- exchange->state);
+ "Processing find operations for `%s'\n",
+ exchange->url);
for (struct TMH_EXCHANGES_KeysOperation *ko = exchange->keys_head;
NULL != ko;
ko = kon)
@@ -699,61 +621,6 @@ process_wire_fees (
/**
- * Add account restriction @a a to array of @a restrictions.
- *
- * @param[in,out] restrictions JSON array to build
- * @param r restriction to add to @a restrictions
- * @return #GNUNET_SYSERR if @a r is malformed
- */
-static enum GNUNET_GenericReturnValue
-add_restriction (json_t *restrictions,
- const struct TALER_EXCHANGE_AccountRestriction *r)
-{
- json_t *jr;
-
- jr = NULL;
- switch (r->type)
- {
- case TALER_EXCHANGE_AR_INVALID:
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- case TALER_EXCHANGE_AR_DENY:
- jr = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("type",
- "deny")
- );
- break;
- case TALER_EXCHANGE_AR_REGEX:
- jr = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string (
- "type",
- "regex"),
- GNUNET_JSON_pack_string (
- "regex",
- r->details.regex.posix_egrep),
- GNUNET_JSON_pack_string (
- "human_hint",
- r->details.regex.human_hint),
- GNUNET_JSON_pack_object_incref (
- "human_hint_i18n",
- (json_t *) r->details.regex.human_hint_i18n)
- );
- break;
- }
- if (NULL == jr)
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- GNUNET_assert (0 ==
- json_array_append_new (restrictions,
- jr));
- return GNUNET_OK;
-
-}
-
-
-/**
* Retry getting keys from the given exchange in the closure.
*
* @param cls the `struct TMH_Exchange *`
@@ -762,49 +629,23 @@ static void
retry_exchange (void *cls)
{
struct TMH_Exchange *exchange = cls;
+ struct GNUNET_DB_EventHeaderP es = {
+ .size = ntohs (sizeof (es)),
+ .type = ntohs (TALER_DBEVENT_MERCHANT_EXCHANGE_FORCE_KEYS)
+ };
exchange->retry_task = NULL;
- GNUNET_assert (NULL == exchange->conn);
exchange->retry_delay
= GNUNET_TIME_randomized_backoff (exchange->retry_delay,
RETRY_BACKOFF_THRESHOLD);
- /* Block for the duration of the long-poller */
exchange->first_retry
- = GNUNET_TIME_relative_to_absolute (LONG_POLL_THRESHOLD);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Fetching /keys from exchange %s in retry_exchange()\n",
- exchange->url);
- switch (exchange->state)
- {
- case ESTATE_FAILED:
- exchange->state = ESTATE_REDOWNLOADING_FAILURE;
- break;
- case ESTATE_INIT:
- exchange->state = ESTATE_DOWNLOADING_FIRST;
- break;
- case ESTATE_DOWNLOADING_FIRST:
- GNUNET_break (0);
- return;
- case ESTATE_DOWNLOADED:
- exchange->state = ESTATE_REDOWNLOADING_SUCCESS;
- break;
- case ESTATE_REDOWNLOADING_SUCCESS:
- GNUNET_break (0);
- return;
- case ESTATE_REDOWNLOADING_FAILURE:
- GNUNET_break (0);
- return;
- }
- exchange->conn
- = TALER_EXCHANGE_get_keys (
- TMH_curl_ctx,
- exchange->url,
- exchange->keys,
- &keys_mgmt_cb,
- exchange);
- /* Note: while the API spec says 'returns NULL on error', the implementation
- actually never returns NULL. */
- GNUNET_break (NULL != exchange->conn);
+ = GNUNET_TIME_relative_to_absolute (
+ exchange->retry_delay);
+
+ TMH_db->event_notify (TMH_db->cls,
+ &es,
+ exchange->url,
+ strlen (exchange->url) + 1);
}
@@ -853,26 +694,25 @@ TMH_EXCHANGES_keys4exchange (
GNUNET_CONTAINER_DLL_insert (exchange->keys_head,
exchange->keys_tail,
fo);
- if ( (NULL != exchange->keys) &&
- (! force_download) &&
- (GNUNET_TIME_absolute_is_future (
- exchange->keys->key_data_expiration.abs_time)) )
+ if ( (NULL == exchange->keys) &&
+ (! force_download) )
{
- /* We have a valid reply, immediately return result */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "The exchange `%s' is ready\n",
+ "Waiting for `%skeys' already, failing query instantly\n",
exchange->url);
GNUNET_assert (NULL == fo->at);
fo->at = GNUNET_SCHEDULER_add_now (&return_keys,
fo);
return fo;
}
- if ( (NULL == exchange->conn) &&
- ( (ESTATE_FAILED == exchange->state) ||
- (ESTATE_REDOWNLOADING_FAILURE == exchange->state) ) )
+ if ( (NULL != exchange->keys) &&
+ (! force_download) &&
+ (GNUNET_TIME_absolute_is_future (
+ exchange->keys->key_data_expiration.abs_time)) )
{
+ /* We have a valid reply, immediately return result */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Already waiting for `%skeys' for a while, failing query instantly\n",
+ "The exchange `%s' is ready\n",
exchange->url);
GNUNET_assert (NULL == fo->at);
fo->at = GNUNET_SCHEDULER_add_now (&return_keys,
@@ -881,7 +721,7 @@ TMH_EXCHANGES_keys4exchange (
}
if ( (force_download) &&
(GNUNET_TIME_absolute_is_future (exchange->first_retry)) &&
- (ESTATE_DOWNLOADED == exchange->state) )
+ (NULL != exchange->keys) )
{
/* Return results immediately. */
fo->at = GNUNET_SCHEDULER_add_now (&return_keys,
@@ -889,16 +729,14 @@ TMH_EXCHANGES_keys4exchange (
/* *no* return here, we MAY schedule a 'retry_task' in the
next block if there isn't one yet */
}
- if ( (NULL == exchange->retry_task) &&
- (NULL == exchange->conn) )
+ if (NULL == exchange->retry_task)
exchange->retry_task
= GNUNET_SCHEDULER_add_at (exchange->first_retry,
&retry_exchange,
exchange);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Next %skeys (%d) request scheduled for %s\n",
+ "Next %skeys request scheduled for %s\n",
exchange->url,
- exchange->state,
GNUNET_TIME_absolute2s (
exchange->first_retry));
/* No activity to launch, we are already doing so. */
@@ -976,10 +814,9 @@ free_exchange_entry (struct TMH_Exchange *exchange)
struct FeesByWireMethod *f;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Releasing %s exchange %s (%d)\n",
+ "Releasing %s exchange %s\n",
exchange->trusted ? "trusted" : "untrusted",
- exchange->url,
- exchange->state);
+ exchange->url);
GNUNET_CONTAINER_DLL_remove (exchange_head,
exchange_tail,
exchange);
@@ -999,11 +836,6 @@ free_exchange_entry (struct TMH_Exchange *exchange)
GNUNET_free (f->wire_method);
GNUNET_free (f);
}
- if (NULL != exchange->conn)
- {
- TALER_EXCHANGE_get_keys_cancel (exchange->conn);
- exchange->conn = NULL;
- }
TALER_EXCHANGE_keys_decref (exchange->keys);
exchange->keys = NULL;
if (NULL != exchange->retry_task)
@@ -1019,281 +851,6 @@ free_exchange_entry (struct TMH_Exchange *exchange)
}
-/**
- * We failed downloading /keys from @a exchange. Tell clients
- * about our failure, abort pending operations and retry later.
- *
- * @param exchange exchange that failed
- */
-static void
-fail_and_retry (struct TMH_Exchange *exchange)
-{
- struct TMH_EXCHANGES_KeysOperation *keys;
-
- exchange->state = ESTATE_FAILED;
- while (NULL != (keys = exchange->keys_head))
- {
- keys->fc (keys->fc_cls,
- NULL,
- exchange);
- TMH_EXCHANGES_keys4exchange_cancel (keys);
- }
- exchange->retry_delay
- = GNUNET_TIME_randomized_backoff (exchange->retry_delay,
- RETRY_BACKOFF_THRESHOLD);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to fetch /keys from `%s'; retrying in %s\n",
- exchange->url,
- GNUNET_STRINGS_relative_time_to_string (exchange->retry_delay,
- true));
- if (NULL != exchange->retry_task)
- GNUNET_SCHEDULER_cancel (exchange->retry_task);
- exchange->first_retry
- = GNUNET_TIME_relative_to_absolute (
- exchange->retry_delay);
- exchange->retry_task
- = GNUNET_SCHEDULER_add_delayed (exchange->retry_delay,
- &retry_exchange,
- exchange);
-}
-
-
-/**
- * Update our information in the database about the
- * /keys of an exchange. Run inside of a database
- * transaction scope that will re-try and/or commit
- * depending on the return value.
- *
- * @param keys information to persist
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-insert_keys_data (const struct TALER_EXCHANGE_Keys *keys)
-{
- enum GNUNET_DB_QueryStatus qs;
-
- /* store exchange online signing keys in our DB */
- for (unsigned int i = 0; i<keys->num_sign_keys; i++)
- {
- struct TALER_EXCHANGE_SigningPublicKey *sign_key = &keys->sign_keys[i];
-
- qs = TMH_db->insert_exchange_signkey (
- TMH_db->cls,
- &keys->master_pub,
- &sign_key->key,
- sign_key->valid_from,
- sign_key->valid_until,
- sign_key->valid_legal,
- &sign_key->master_sig);
- /* 0 is OK, we may already have the key in the DB! */
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- }
-
- qs = TMH_db->insert_exchange_keys (TMH_db->cls,
- keys);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
-
- qs = TMH_db->delete_exchange_accounts (TMH_db->cls,
- &keys->master_pub);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
-
- for (unsigned int i = 0; i<keys->accounts_len; i++)
- {
- const struct TALER_EXCHANGE_WireAccount *account = &keys->accounts[i];
- json_t *debit_restrictions;
- json_t *credit_restrictions;
-
- debit_restrictions = json_array ();
- GNUNET_assert (NULL != debit_restrictions);
- credit_restrictions = json_array ();
- GNUNET_assert (NULL != credit_restrictions);
- for (unsigned int j = 0; j<account->debit_restrictions_length; j++)
- {
- if (GNUNET_OK !=
- add_restriction (debit_restrictions,
- &account->debit_restrictions[j]))
- {
- TMH_db->rollback (TMH_db->cls);
- GNUNET_break (0);
- json_decref (debit_restrictions);
- json_decref (credit_restrictions);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- for (unsigned int j = 0; j<account->credit_restrictions_length; j++)
- {
- if (GNUNET_OK !=
- add_restriction (credit_restrictions,
- &account->credit_restrictions[j]))
- {
- TMH_db->rollback (TMH_db->cls);
- GNUNET_break (0);
- json_decref (debit_restrictions);
- json_decref (credit_restrictions);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- qs = TMH_db->insert_exchange_account (
- TMH_db->cls,
- &keys->master_pub,
- account->payto_uri,
- account->conversion_url,
- debit_restrictions,
- credit_restrictions,
- &account->master_sig);
- json_decref (debit_restrictions);
- json_decref (credit_restrictions);
- if (qs < 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- } /* end 'for all accounts' */
-
- for (unsigned int i = 0; i<keys->fees_len; i++)
- {
- const struct TALER_EXCHANGE_WireFeesByMethod *fbm = &keys->fees[i];
- const char *wire_method = fbm->method;
- const struct TALER_EXCHANGE_WireAggregateFees *fees = fbm->fees_head;
-
- while (NULL != fees)
- {
- struct GNUNET_HashCode h_wire_method;
-
- GNUNET_CRYPTO_hash (wire_method,
- strlen (wire_method) + 1,
- &h_wire_method);
- qs = TMH_db->store_wire_fee_by_exchange (TMH_db->cls,
- &keys->master_pub,
- &h_wire_method,
- &fees->fees,
- fees->start_date,
- fees->end_date,
- &fees->master_sig);
- if (0 > qs)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- fees = fees->next;
- } /* all fees for this method */
- } /* for all methods (i) */
-
- {
- struct GNUNET_DB_EventHeaderP es = {
- .size = ntohs (sizeof (es)),
- .type = ntohs (TALER_DBEVENT_MERCHANT_EXCHANGE_KEYS)
- };
-
- TMH_db->event_notify (TMH_db->cls,
- &es,
- keys->exchange_url,
- strlen (keys->exchange_url) + 1);
- }
- return qs;
-}
-
-
-static void
-keys_mgmt_cb (void *cls,
- const struct TALER_EXCHANGE_KeysResponse *kr,
- struct TALER_EXCHANGE_Keys *keys)
-{
- struct TMH_Exchange *exchange = cls;
- enum GNUNET_DB_QueryStatus qs;
-
- exchange->conn = NULL;
- if (MHD_HTTP_OK != kr->hr.http_status)
- {
- if (GNUNET_TIME_absolute_is_future (exchange->first_retry))
- {
- /* /keys failed *before* the long polling threshold.
- We apply the exponential back-off from now. */
- exchange->first_retry
- = GNUNET_TIME_relative_to_absolute (
- exchange->retry_delay);
- }
- fail_and_retry (exchange);
- TALER_EXCHANGE_keys_decref (keys);
- return;
- }
- if (NULL == exchange->currency)
- exchange->currency = GNUNET_strdup (keys->currency);
- if (0 != strcmp (exchange->currency,
- keys->currency))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "/keys response from `%s' is for currency `%s', but we expected `%s'\n",
- exchange->url,
- keys->currency,
- exchange->currency);
- fail_and_retry (exchange);
- TALER_EXCHANGE_keys_decref (keys);
- return;
- }
- exchange->state = ESTATE_DOWNLOADED;
- TMH_db->preflight (TMH_db->cls);
- for (unsigned int r = 0; r<MAX_RETRIES; r++)
- {
- if (GNUNET_OK !=
- TMH_db->start (TMH_db->cls,
- "update exchange key data"))
- {
- TMH_db->rollback (TMH_db->cls);
- GNUNET_break (0);
- fail_and_retry (exchange);
- TALER_EXCHANGE_keys_decref (keys);
- return;
- }
-
- qs = insert_keys_data (keys);
- if (qs < 0)
- {
- TMH_db->rollback (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- continue;
- GNUNET_break (0);
- fail_and_retry (exchange);
- TALER_EXCHANGE_keys_decref (keys);
- return;
- }
-
- qs = TMH_db->commit (TMH_db->cls);
- if (qs < 0)
- {
- TMH_db->rollback (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- continue;
- GNUNET_break (0);
- fail_and_retry (exchange);
- TALER_EXCHANGE_keys_decref (keys);
- return;
- }
- } /* end of retry loop */
- if (qs < 0)
- {
- GNUNET_break (0);
- fail_and_retry (exchange);
- TALER_EXCHANGE_keys_decref (keys);
- return;
- }
- TALER_EXCHANGE_keys_decref (keys);
- exchange->retry_delay = GNUNET_TIME_UNIT_ZERO;
-}
-
-
enum GNUNET_GenericReturnValue
TMH_EXCHANGES_lookup_wire_fee (
const struct TMH_Exchange *exchange,
@@ -1326,6 +883,7 @@ TMH_exchange_check_debit (
exchange->url);
return GNUNET_SYSERR;
}
+ /* FIXME: move into convenience function in libtalerexchange? See also taler-merchant-httpd_private-get-instances-ID-kyc.c, taler-merchant-kyccheck (!) */
for (struct ExchangeAccount *acc = exchange->acc_head;
NULL != acc;
acc = acc->next)
@@ -1432,6 +990,107 @@ TMH_test_exchange_configured_for_currency (
/**
+ * (Re)load of keys from DB.
+ *
+ * @param exchange exchange to reload keys of
+ */
+static void
+reload_exchange_keys (struct TMH_Exchange *exchange)
+{
+ enum GNUNET_DB_QueryStatus qs;
+ struct TALER_EXCHANGE_Keys *keys;
+
+ qs = TMH_db->select_exchange_keys (TMH_db->cls,
+ exchange->url,
+ &keys);
+ if (qs < 0)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "No keys yet for `%s'\n",
+ exchange->url);
+ return;
+ }
+ exchange->retry_delay = GNUNET_TIME_UNIT_ZERO;
+ if (NULL == exchange->currency)
+ exchange->currency = GNUNET_strdup (keys->currency);
+ if (0 != strcmp (keys->currency,
+ exchange->currency))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "/keys cached in our database are for currency `%s', but we expected `%s'\n",
+ keys->currency,
+ exchange->currency);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Loaded /keys from database with %u accounts\n",
+ keys->accounts_len);
+ if (GNUNET_OK !=
+ set_exchange_accounts (exchange,
+ keys->accounts_len,
+ keys->accounts))
+ {
+ /* invalid account specification given */
+ GNUNET_break_op (0);
+ /* but: we can continue anyway, things may just not
+ work, but probably better than to not keep going. */
+ }
+ if (GNUNET_OK !=
+ process_wire_fees (exchange,
+ &keys->master_pub,
+ keys->fees_len,
+ keys->fees))
+ {
+ /* invalid wire fee specification given */
+ GNUNET_break_op (0);
+ /* but: we can continue anyway, things may just not
+ work, but probably better than to not keep going. */
+ return;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Reloaded /keys of %s from database\n",
+ exchange->url);
+ TALER_EXCHANGE_keys_decref (exchange->keys);
+ exchange->keys = keys;
+ if ( (exchange->trusted) &&
+ (0 != GNUNET_memcmp (&exchange->master_pub,
+ &keys->master_pub)) )
+ {
+ /* master pub differs => do not trust the exchange (without auditor) */
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Master public key of exchange `%s' differs from our configuration. Not trusting exchange.\n",
+ exchange->url);
+ exchange->trusted = false;
+ }
+ if (! exchange->trusted)
+ {
+ exchange->master_pub = keys->master_pub;
+ for (struct TMH_Exchange *e = exchange_head;
+ NULL != e;
+ e = e->next)
+ {
+ if (e == exchange)
+ continue;
+ if (! e->trusted)
+ continue;
+ if (0 ==
+ GNUNET_memcmp (&e->master_pub,
+ &exchange->master_pub))
+ exchange->trusted = true; /* same exchange, different URL => trust applies */
+ }
+ }
+
+ process_find_operations (exchange);
+}
+
+
+/**
* Function called on each configuration section. Finds sections
* about exchanges, parses the entries.
*
@@ -1484,10 +1143,7 @@ accept_exchanges (void *cls,
}
exchange = lookup_exchange (url);
GNUNET_free (url);
- if (NULL == exchange->currency)
- exchange->currency = currency;
- else
- GNUNET_free (currency);
+ exchange->currency = currency;
if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
@@ -1522,6 +1178,7 @@ accept_exchanges (void *cls,
"Setup exchange %s as %s\n",
exchange->url,
exchange->trusted ? "trusted" : "untrusted");
+ reload_exchange_keys (exchange);
if (NULL != exchange->retry_task)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1549,10 +1206,8 @@ update_exchange_keys (void *cls,
const void *extra,
size_t extra_len)
{
- enum GNUNET_DB_QueryStatus qs;
const char *url = extra;
struct TMH_Exchange *exchange;
- struct TALER_EXCHANGE_Keys *keys;
if ( (NULL == extra) ||
(0 == extra_len) )
@@ -1569,85 +1224,7 @@ update_exchange_keys (void *cls,
"Received keys change notification: reload `%s'\n",
url);
exchange = lookup_exchange (url);
- qs = TMH_db->select_exchange_keys (TMH_db->cls,
- url,
- &keys);
- if (qs <= 0)
- {
- GNUNET_break (0);
- return;
- }
- if (NULL == exchange->currency)
- exchange->currency = GNUNET_strdup (keys->currency);
- if (0 != strcmp (keys->currency,
- exchange->currency))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "/keys cached in our database are for currency `%s', but we expected `%s'\n",
- keys->currency,
- exchange->currency);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Loaded /keys from database with %u accounts\n",
- keys->accounts_len);
- if (GNUNET_OK !=
- set_exchange_accounts (exchange,
- keys->accounts_len,
- keys->accounts))
- {
- /* invalid account specification given */
- GNUNET_break_op (0);
- /* but: we can continue anyway, things may just not
- work, but probably better than to not keep going. */
- }
- if (GNUNET_OK !=
- process_wire_fees (exchange,
- &keys->master_pub,
- keys->fees_len,
- keys->fees))
- {
- /* invalid wire fee specification given */
- GNUNET_break_op (0);
- /* but: we can continue anyway, things may just not
- work, but probably better than to not keep going. */
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Reloaded /keys of %s from database\n",
- url);
- TALER_EXCHANGE_keys_decref (exchange->keys);
- exchange->keys = keys;
- if ( (exchange->trusted) &&
- (0 != GNUNET_memcmp (&exchange->master_pub,
- &keys->master_pub)) )
- {
- /* master pub differs => do not trust the exchange (without auditor) */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Master public key of exchange `%s' differs from our configuration. Not trusting exchange.\n",
- exchange->url);
- exchange->trusted = false;
- }
- if (! exchange->trusted)
- {
- exchange->master_pub = keys->master_pub;
- for (struct TMH_Exchange *e = exchange_head;
- NULL != e;
- e = e->next)
- {
- if (e == exchange)
- continue;
- if (! e->trusted)
- continue;
- if (0 ==
- GNUNET_memcmp (&e->master_pub,
- &exchange->master_pub))
- exchange->trusted = true; /* same exchange, different URL => trust applies */
- }
- }
-
- process_find_operations (exchange);
+ reload_exchange_keys (exchange);
}
diff --git a/src/backend/taler-merchant-kyccheck.c b/src/backend/taler-merchant-kyccheck.c
index c55b12c4..933d0984 100644
--- a/src/backend/taler-merchant-kyccheck.c
+++ b/src/backend/taler-merchant-kyccheck.c
@@ -645,7 +645,7 @@ is_eligible (struct TALER_EXCHANGE_Keys *keys,
/* For all accounts of the exchange */
for (unsigned int i = 0; i<keys->accounts_len; i++)
{
- /* FIXME: move into convenience function in libtalerexchange? See also taler-merchant-httpd_private-get-instances-ID-kyc.c*/
+ /* FIXME: move into convenience function in libtalerexchange? See also taler-merchant-httpd_private-get-instances-ID-kyc.c, taler-merchant-httpd_exchanges (!)*/
struct TALER_EXCHANGE_WireAccount *account
= &keys->accounts[i];
bool account_restricted = false;
diff --git a/src/testing/test_merchant_instance_auth.sh b/src/testing/test_merchant_instance_auth.sh
index 85857b4f..1959628b 100755
--- a/src/testing/test_merchant_instance_auth.sh
+++ b/src/testing/test_merchant_instance_auth.sh
@@ -72,6 +72,7 @@ setup -c test_template.conf -ef -u "exchange-account-2"
NEW_SECRET=secret-token:different_value
+taler-merchant-exchangekeyupdate -c "${CONF}" -L DEBUG 2> taler-merchant-exchangekeyupdate.log &
taler-merchant-httpd -a "${NEW_SECRET}" -c "${CONF}" -L DEBUG 2> taler-merchant-httpd.log &
# Install cleanup handler (except for kill -9)
trap my_cleanup EXIT