[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-exchange] branch master updated: -fix warnings
From: |
gnunet |
Subject: |
[taler-exchange] branch master updated: -fix warnings |
Date: |
Mon, 02 Sep 2024 15:46:28 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository exchange.
The following commit(s) were added to refs/heads/master by this push:
new 5119a75cb -fix warnings
5119a75cb is described below
commit 5119a75cbc5473498a17855745a991df95e746d5
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Sep 2 15:46:22 2024 +0200
-fix warnings
---
src/auditordb/test_auditordb.c | 21 +-
src/exchange/taler-exchange-aggregator.c | 12 +-
src/exchange/taler-exchange-httpd_age-withdraw.c | 5 +-
src/exchange/taler-exchange-httpd_batch-deposit.c | 20 +-
src/exchange/taler-exchange-httpd_batch-withdraw.c | 5 +-
src/exchange/taler-exchange-httpd_common_kyc.c | 223 +++++++++++++++++++--
src/exchange/taler-exchange-httpd_common_kyc.h | 38 ++++
src/exchange/taler-exchange-httpd_kyc-wallet.c | 3 +-
src/exchange/taler-exchange-httpd_purses_merge.c | 8 +-
src/exchange/taler-exchange-httpd_reserves_close.c | 5 +-
src/exchange/taler-exchange-httpd_reserves_purse.c | 8 +-
src/exchange/taler-exchange-httpd_responses.c | 20 +-
src/exchange/taler-exchange-httpd_responses.h | 12 +-
.../exchange_do_trigger_kyc_rule_for_account.sql | 31 ++-
src/exchangedb/pg_get_kyc_rules.c | 13 +-
src/exchangedb/pg_get_kyc_rules.h | 3 +
src/exchangedb/pg_trigger_kyc_rule_for_account.c | 20 +-
src/exchangedb/pg_trigger_kyc_rule_for_account.h | 13 +-
src/include/taler_exchange_service.h | 7 +-
src/include/taler_exchangedb_plugin.h | 29 ++-
src/json/test_json.c | 4 +-
src/lib/exchange_api_batch_deposit.c | 3 +
22 files changed, 431 insertions(+), 72 deletions(-)
diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c
index ab08a9bb7..c859e7239 100644
--- a/src/auditordb/test_auditordb.c
+++ b/src/auditordb/test_auditordb.c
@@ -185,6 +185,15 @@ run (void *cls)
{
struct GNUNET_CONFIGURATION_Handle *cfg = cls;
uint64_t rowid;
+ struct TALER_Amount value;
+ struct TALER_Amount fee_withdraw;
+ struct TALER_Amount fee_deposit;
+ struct TALER_Amount fee_refresh;
+ struct TALER_Amount fee_refund;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_DenominationPrivateKey denom_priv;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct GNUNET_TIME_Timestamp date;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"loading database plugin\n");
@@ -219,12 +228,6 @@ run (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"initializing\n");
- struct TALER_Amount value;
- struct TALER_Amount fee_withdraw;
- struct TALER_Amount fee_deposit;
- struct TALER_Amount fee_refresh;
- struct TALER_Amount fee_refund;
-
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (CURRENCY ":1.000010",
&value));
@@ -240,12 +243,6 @@ run (void *cls)
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (CURRENCY ":0.000014",
&fee_refund));
-
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_DenominationPrivateKey denom_priv;
- struct TALER_DenominationPublicKey denom_pub;
- struct GNUNET_TIME_Timestamp date;
-
RND_BLK (&reserve_pub);
RND_BLK (&rnd_hash);
GNUNET_assert (GNUNET_OK ==
diff --git a/src/exchange/taler-exchange-aggregator.c
b/src/exchange/taler-exchange-aggregator.c
index 3776817d2..37a84fa14 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -111,6 +111,12 @@ struct AggregationUnit
*/
bool have_transient;
+ /**
+ * Is the wrong merchant public key associated with
+ * the KYC data?
+ */
+ bool bad_kyc_auth;
+
};
@@ -515,9 +521,11 @@ legitimization_satisfied (struct AggregationUnit
*au_active)
{
json_t *jrules;
+ union TALER_AccountPublicKeyP account_pub;
qs = db_plugin->get_kyc_rules (db_plugin->cls,
&au_active->h_payto,
+ &account_pub,
&jrules);
if (qs < 0)
{
@@ -564,9 +572,11 @@ legitimization_satisfied (struct AggregationUnit
*au_active)
au_active->payto_uri,
&au_active->h_payto,
NULL,
+ &au_active->merchant_pub,
jrule,
TALER_KYCLOGIC_rule2priority (requirement),
- &au_active->requirement_row);
+ &au_active->requirement_row,
+ &au_active->bad_kyc_auth);
json_decref (jrule);
if (qs < 0)
{
diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c
b/src/exchange/taler-exchange-httpd_age-withdraw.c
index dbfc9b5e7..e7d4b139c 100644
--- a/src/exchange/taler-exchange-httpd_age-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_age-withdraw.c
@@ -499,7 +499,8 @@ check_kyc_result (struct AgeWithdrawContext *awc)
TEH_RESPONSE_reply_kyc_required (
awc->rc->connection,
&awc->h_payto,
- &awc->kyc));
+ &awc->kyc,
+ false));
return;
}
awc->phase++;
@@ -630,7 +631,7 @@ run_legi_check (struct AgeWithdrawContext *awc)
TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW,
payto_uri,
&awc->h_payto,
- NULL,
+ NULL, /* no account pub: this is about the origin account */
&withdraw_amount_cb,
awc,
&withdraw_legi_cb,
diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c
b/src/exchange/taler-exchange-httpd_batch-deposit.c
index cb15ff85f..abebe51ca 100644
--- a/src/exchange/taler-exchange-httpd_batch-deposit.c
+++ b/src/exchange/taler-exchange-httpd_batch-deposit.c
@@ -160,6 +160,12 @@ struct BatchDepositContext
* @e policy_json is NULL and @e h_policy will be all zero.
*/
bool has_no_policy;
+
+ /**
+ * KYC failed because a KYC auth transfer is needed
+ * to establish the merchant_pub.
+ */
+ bool bad_kyc_auth;
};
@@ -488,7 +494,8 @@ static void
bdc_phase_check_kyc_result (struct BatchDepositContext *bdc)
{
/* return final positive response */
- if (! bdc->kyc.ok)
+ if ( (! bdc->kyc.ok) ||
+ (bdc->bad_kyc_auth) )
{
if (check_request_idempotent (bdc))
{
@@ -501,7 +508,8 @@ bdc_phase_check_kyc_result (struct BatchDepositContext *bdc)
TEH_RESPONSE_reply_kyc_required (
bdc->rc->connection,
&bdc->bd.wire_target_h_payto,
- &bdc->kyc));
+ &bdc->kyc,
+ bdc->bad_kyc_auth));
return;
}
bdc->phase = BDC_PHASE_TRANSACT;
@@ -538,6 +546,7 @@ deposit_legi_cb (
return;
}
bdc->kyc = lcr->kyc;
+ bdc->bad_kyc_auth = lcr->bad_kyc_auth;
bdc->phase = BDC_PHASE_CHECK_KYC_RESULT;
}
@@ -604,15 +613,12 @@ bdc_phase_kyc (struct BatchDepositContext *bdc)
bdc->phase++;
return;
}
- /* FIXME: this fails to check that the
- merchant_pub used in this request
- matches the registered public key */
- bdc->lch = TEH_legitimization_check (
+ bdc->lch = TEH_legitimization_check2 (
&bdc->rc->async_scope_id,
TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT,
bdc->bd.receiver_wire_account,
&bdc->bd.wire_target_h_payto,
- NULL, /* account_pub */
+ &bdc->bd.merchant_pub,
&deposit_amount_cb,
bdc,
&deposit_legi_cb,
diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c
b/src/exchange/taler-exchange-httpd_batch-withdraw.c
index 6fb3c5447..5119a3e4b 100644
--- a/src/exchange/taler-exchange-httpd_batch-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c
@@ -571,7 +571,8 @@ check_kyc_result (struct BatchWithdrawContext *bwc)
TEH_RESPONSE_reply_kyc_required (
bwc->rc->connection,
&bwc->h_payto,
- &bwc->kyc));
+ &bwc->kyc,
+ false));
return;
}
bwc->phase++;
@@ -702,7 +703,7 @@ run_legi_check (struct BatchWithdrawContext *bwc)
TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW,
payto_uri,
&bwc->h_payto,
- NULL,
+ NULL, /* no account pub: this is about the origin account */
&withdraw_amount_cb,
bwc,
&withdraw_legi_cb,
diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c
b/src/exchange/taler-exchange-httpd_common_kyc.c
index 20d8b0ecf..45e217523 100644
--- a/src/exchange/taler-exchange-httpd_common_kyc.c
+++ b/src/exchange/taler-exchange-httpd_common_kyc.c
@@ -922,16 +922,19 @@ TEH_kyc_fallback (
{
json_t *jmeasures;
enum GNUNET_DB_QueryStatus qs;
+ bool bad_kyc_auth;
jmeasures = TALER_KYCLOGIC_check_to_measures (&kcc);
qs = TEH_plugin->trigger_kyc_rule_for_account (
TEH_plugin->cls,
NULL, /* account_id is already in wire targets */
account_id,
- NULL,
+ NULL, /* account_pub */
+ NULL, /* merchant_pub */
jmeasures,
65536, /* high priority (does it matter?) */
- &fb->requirement_row);
+ &fb->requirement_row,
+ &bad_kyc_auth);
json_decref (jmeasures);
fb->failure = (qs <= 0);
fb->task = GNUNET_SCHEDULER_add_now (&return_fallback_result,
@@ -1043,10 +1046,19 @@ struct TEH_LegitimizationCheckHandle
struct TALER_PaytoHashP h_payto;
/**
- * Public key of the account.
+ * Public key of the account. Associates this public
+ * key with the account if @e have_account_pub is true.
*/
union TALER_AccountPublicKeyP account_pub;
+ /**
+ * Public key of the merchant. Checks that the KYC
+ * data was actually provided for this merchant if
+ * @e have_merchant_pub is true, and if not rejects
+ * the operation.
+ */
+ struct TALER_MerchantPublicKeyP merchant_pub;
+
/**
* Our request scope for logging.
*/
@@ -1073,6 +1085,18 @@ struct TEH_LegitimizationCheckHandle
* Do we have @e account_pub?
*/
bool have_account_pub;
+
+ /**
+ * Do we have @e merchant_pub?
+ */
+ bool have_merchant_pub;
+
+ /**
+ * True if @a have_merchant_pub is true but the given
+ * merchant pub did not match the target_pub for the
+ * given @a h_payto.
+ */
+ bool bad_kyc_auth;
};
@@ -1176,8 +1200,23 @@ legi_check_aml_trigger_cb (
}
-struct TEH_LegitimizationCheckHandle *
-TEH_legitimization_check (
+/**
+ * Setup legitimization check.
+ *
+ * @param scope scope for logging
+ * @param et type of event we are checking
+ * @param payto_uri account we are checking for
+ * @param h_payto hash of @a payto_uri
+ * @param account_pub public key to enable for the
+ * KYC authorization, NULL if not known
+ * @param ai callback to get amounts involved historically
+ * @param ai_cls closure for @a ai
+ * @param result_cb function to call with the result
+ * @param result_cb_cls closure for @a result_cb
+ * @return handle for the operation
+ */
+static struct TEH_LegitimizationCheckHandle *
+setup_legitimization_check (
const struct GNUNET_AsyncScopeId *scope,
enum TALER_KYCLOGIC_KycTriggerEvent et,
const char *payto_uri,
@@ -1204,6 +1243,63 @@ TEH_legitimization_check (
lch->ai_cls = ai_cls;
lch->result_cb = result_cb;
lch->result_cb_cls = result_cb_cls;
+ return lch;
+}
+
+
+struct TEH_LegitimizationCheckHandle *
+TEH_legitimization_check (
+ const struct GNUNET_AsyncScopeId *scope,
+ enum TALER_KYCLOGIC_KycTriggerEvent et,
+ const char *payto_uri,
+ const struct TALER_PaytoHashP *h_payto,
+ const union TALER_AccountPublicKeyP *account_pub,
+ TALER_KYCLOGIC_KycAmountIterator ai,
+ void *ai_cls,
+ TEH_LegitimizationCheckCallback result_cb,
+ void *result_cb_cls)
+{
+ struct TEH_LegitimizationCheckHandle *lch;
+
+ lch = setup_legitimization_check (scope,
+ et,
+ payto_uri,
+ h_payto,
+ account_pub,
+ ai,
+ ai_cls,
+ result_cb,
+ result_cb_cls);
+ legitimization_check_run (lch);
+ return lch;
+}
+
+
+struct TEH_LegitimizationCheckHandle *
+TEH_legitimization_check2 (
+ const struct GNUNET_AsyncScopeId *scope,
+ enum TALER_KYCLOGIC_KycTriggerEvent et,
+ const char *payto_uri,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ TALER_KYCLOGIC_KycAmountIterator ai,
+ void *ai_cls,
+ TEH_LegitimizationCheckCallback result_cb,
+ void *result_cb_cls)
+{
+ struct TEH_LegitimizationCheckHandle *lch;
+
+ lch = setup_legitimization_check (scope,
+ et,
+ payto_uri,
+ h_payto,
+ NULL,
+ ai,
+ ai_cls,
+ result_cb,
+ result_cb_cls);
+ lch->merchant_pub = *merchant_pub;
+ lch->have_merchant_pub = true;
legitimization_check_run (lch);
return lch;
}
@@ -1396,9 +1492,11 @@ run_check (
lch->payto_uri,
&lch->h_payto,
lch->have_account_pub ? &lch->account_pub : NULL,
+ lch->have_merchant_pub ? &lch->merchant_pub : NULL,
jmeasures,
0, /* no particular priority */
- &lch->lcr.kyc.requirement_row);
+ &lch->lcr.kyc.requirement_row,
+ &lch->lcr.bad_kyc_auth);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -1428,6 +1526,74 @@ cleanup:
}
+/**
+ * The KYC check failed because KYC auth is required
+ * to match and it does not.
+ *
+ * @param[in,out] lch legitimization check to fail
+ */
+static void
+fail_kyc_auth (struct TEH_LegitimizationCheckHandle *lch)
+{
+ lch->lcr.kyc.requirement_row = 0;
+ lch->lcr.kyc.ok = false;
+ lch->lcr.bad_kyc_auth = true;
+ lch->lcr.expiration_date
+ = GNUNET_TIME_UNIT_FOREVER_TS;
+ memset (&lch->lcr.next_threshold,
+ 0,
+ sizeof (struct TALER_Amount));
+ lch->lcr.http_status = 0;
+ lch->lcr.response = NULL;
+ lch->async_task
+ = GNUNET_SCHEDULER_add_now (
+ &async_return_legi_result,
+ lch);
+}
+
+
+/**
+ * Function called to iterate over KYC-relevant
+ * transaction amounts for a particular time range.
+ * Called within a database transaction, so must
+ * not start a new one.
+ *
+ * Given that there *is* a KYC requirement, we also
+ * check if the kyc_auth_bad is set and react
+ * accordingly.
+ *
+ * @param cls closure, a `struct TEH_LegitimizationCheckHandle *`
+ * @param limit maximum time-range for which events
+ * should be fetched (timestamp in the past)
+ * @param cb function to call on each event found,
+ * events must be returned in reverse chronological
+ * order
+ * @param cb_cls closure for @a cb
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+amount_iterator_wrapper_cb (
+ void *cls,
+ struct GNUNET_TIME_Absolute limit,
+ TALER_EXCHANGEDB_KycAmountCallback cb,
+ void *cb_cls)
+{
+ struct TEH_LegitimizationCheckHandle *lch = cls;
+
+ if (lch->bad_kyc_auth)
+ {
+ /* We *do* have applicable KYC rules *and* the
+ target_pub does not match the merchant_pub,
+ so we indeed have a problem! */
+ lch->lcr.bad_kyc_auth = true;
+ }
+ return lch->ai (lch->ai_cls,
+ limit,
+ cb,
+ cb_cls);
+}
+
+
static void
legitimization_check_run (
struct TEH_LegitimizationCheckHandle *lch)
@@ -1443,6 +1609,7 @@ legitimization_check_run (
/* AML/KYC disabled, just immediately return success! */
lch->lcr.kyc.requirement_row = 0;
lch->lcr.kyc.ok = true;
+ lch->lcr.bad_kyc_auth = false;
lch->lcr.expiration_date
= GNUNET_TIME_UNIT_FOREVER_TS;
memset (&lch->lcr.next_threshold,
@@ -1461,24 +1628,47 @@ legitimization_check_run (
{
json_t *jrules;
+
qs = TEH_plugin->get_kyc_rules (TEH_plugin->cls,
&lch->h_payto,
+ &lch->lcr.kyc.account_pub,
&jrules);
- if (qs < 0)
+ switch (qs)
{
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0);
legi_fail (lch,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"get_kyc_rules");
GNUNET_async_scope_restore (&old_scope);
return;
- }
- if (qs > 0)
- {
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ if (lch->have_merchant_pub)
+ {
+ // FIXME: not quite correct: the absence of custom *jrules* does NOT
+ // imply that we had no target_pub!
+ lch->lcr.bad_kyc_auth = true;
+ }
+ break;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ lch->lcr.kyc.have_account_pub
+ = ! GNUNET_is_zero (&lch->lcr.kyc.account_pub);
+ if ( (lch->have_merchant_pub) &&
+ (0 != GNUNET_memcmp (&lch->merchant_pub,
+ &lch->lcr.kyc.account_pub.merchant_pub)) )
+ {
+ /* We have custom rules, but the target_pub for
+ those custom rules does not match the
+ merchant_pub. Fail the KYC process! */
+ fail_kyc_auth (lch);
+ return;
+ }
lrs = TALER_KYCLOGIC_rules_parse (jrules);
GNUNET_break (NULL != lrs);
/* Fall back to default rules on parse error! */
json_decref (jrules);
+ break;
}
}
@@ -1517,8 +1707,8 @@ legitimization_check_run (
qs = TALER_KYCLOGIC_kyc_test_required (
lch->et,
lrs,
- lch->ai,
- lch->ai_cls,
+ &amount_iterator_wrapper_cb,
+ lch,
&requirement,
&lch->lcr.next_threshold);
if (qs < 0)
@@ -1530,6 +1720,11 @@ legitimization_check_run (
GNUNET_async_scope_restore (&old_scope);
return;
}
+ if (lch->lcr.bad_kyc_auth)
+ {
+ fail_kyc_auth (lch);
+ return;
+ }
if (NULL == requirement)
{
@@ -1606,9 +1801,11 @@ legitimization_check_run (
lch->payto_uri,
&lch->h_payto,
lch->have_account_pub ? &lch->account_pub : NULL,
+ lch->have_merchant_pub ? &lch->merchant_pub : NULL,
jmeasures,
TALER_KYCLOGIC_rule2priority (requirement),
- &lch->lcr.kyc.requirement_row);
+ &lch->lcr.kyc.requirement_row,
+ &lch->lcr.bad_kyc_auth);
json_decref (jmeasures);
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
diff --git a/src/exchange/taler-exchange-httpd_common_kyc.h
b/src/exchange/taler-exchange-httpd_common_kyc.h
index cd753746b..a671d9f44 100644
--- a/src/exchange/taler-exchange-httpd_common_kyc.h
+++ b/src/exchange/taler-exchange-httpd_common_kyc.h
@@ -211,6 +211,14 @@ struct TEH_LegitimizationCheckResult
*/
unsigned int http_status;
+ /**
+ * Set to true if the merchant public key does not
+ * match the public key we have on file for this
+ * target account (and thus a new KYC AUTH is
+ * required).
+ */
+ bool bad_kyc_auth;
+
/**
* Response to return. Note that the response must
* be queued or destroyed by the callee. NULL
@@ -267,6 +275,36 @@ TEH_legitimization_check (
void *result_cb_cls);
+/**
+ * Do legitimization check and enforce that the current
+ * public key associated with the account is the given
+ * merchant public key.
+ *
+ * @param scope scope for logging
+ * @param et type of event we are checking
+ * @param payto_uri account we are checking for
+ * @param h_payto hash of @a payto_uri
+ * @param merchant_pub public key that must match the
+ * KYC authorization
+ * @param ai callback to get amounts involved historically
+ * @param ai_cls closure for @a ai
+ * @param result_cb function to call with the result
+ * @param result_cb_cls closure for @a result_cb
+ * @return handle for the operation
+ */
+struct TEH_LegitimizationCheckHandle *
+TEH_legitimization_check2 (
+ const struct GNUNET_AsyncScopeId *scope,
+ enum TALER_KYCLOGIC_KycTriggerEvent et,
+ const char *payto_uri,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ TALER_KYCLOGIC_KycAmountIterator ai,
+ void *ai_cls,
+ TEH_LegitimizationCheckCallback result_cb,
+ void *result_cb_cls);
+
+
/**
* Cancel legitimization check.
*
diff --git a/src/exchange/taler-exchange-httpd_kyc-wallet.c
b/src/exchange/taler-exchange-httpd_kyc-wallet.c
index 4945881b5..903d87de0 100644
--- a/src/exchange/taler-exchange-httpd_kyc-wallet.c
+++ b/src/exchange/taler-exchange-httpd_kyc-wallet.c
@@ -321,7 +321,8 @@ TEH_handler_kyc_wallet (
}
return TEH_RESPONSE_reply_kyc_required (rc->connection,
&krc->h_payto,
- &krc->kyc);
+ &krc->kyc,
+ false);
}
diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c
b/src/exchange/taler-exchange-httpd_purses_merge.c
index 86c0414f7..0f6a1e498 100644
--- a/src/exchange/taler-exchange-httpd_purses_merge.c
+++ b/src/exchange/taler-exchange-httpd_purses_merge.c
@@ -763,9 +763,11 @@ TEH_handler_purses_merge (
pmc->response);
}
if (! pmc->kyc.ok)
- return TEH_RESPONSE_reply_kyc_required (rc->connection,
- &pmc->h_payto,
- &pmc->kyc);
+ return TEH_RESPONSE_reply_kyc_required (
+ rc->connection,
+ &pmc->h_payto,
+ &pmc->kyc,
+ false);
/* execute merge transaction */
{
diff --git a/src/exchange/taler-exchange-httpd_reserves_close.c
b/src/exchange/taler-exchange-httpd_reserves_close.c
index 98873529a..bf5815f78 100644
--- a/src/exchange/taler-exchange-httpd_reserves_close.c
+++ b/src/exchange/taler-exchange-httpd_reserves_close.c
@@ -343,7 +343,7 @@ reserve_close_transaction (
TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE,
rcc->payto_uri,
&rcc->kyc_payto,
- NULL, /* no account_pub */
+ NULL, /* no account_pub: this is about the origin/destination account */
&amount_it,
rcc,
&reserve_close_legi_cb,
@@ -548,7 +548,8 @@ TEH_handler_reserves_close (
return TEH_RESPONSE_reply_kyc_required (
rc->connection,
&rcc->kyc_payto,
- &rcc->kyc);
+ &rcc->kyc,
+ false);
}
if (GNUNET_OK !=
diff --git a/src/exchange/taler-exchange-httpd_reserves_purse.c
b/src/exchange/taler-exchange-httpd_reserves_purse.c
index 1240de625..d5a111d5a 100644
--- a/src/exchange/taler-exchange-httpd_reserves_purse.c
+++ b/src/exchange/taler-exchange-httpd_reserves_purse.c
@@ -850,9 +850,11 @@ TEH_handler_reserves_purse (
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
"requirement row not set");
}
- return TEH_RESPONSE_reply_kyc_required (connection,
- &rpc->h_payto,
- &rpc->kyc);
+ return TEH_RESPONSE_reply_kyc_required (
+ connection,
+ &rpc->h_payto,
+ &rpc->kyc,
+ false);
}
{
diff --git a/src/exchange/taler-exchange-httpd_responses.c
b/src/exchange/taler-exchange-httpd_responses.c
index 589cef2b1..0405c28fd 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -338,9 +338,11 @@ TEH_RESPONSE_reply_purse_created (
MHD_RESULT
-TEH_RESPONSE_reply_kyc_required (struct MHD_Connection *connection,
- const struct TALER_PaytoHashP *h_payto,
- const struct TALER_EXCHANGEDB_KycStatus *kyc)
+TEH_RESPONSE_reply_kyc_required (
+ struct MHD_Connection *connection,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_EXCHANGEDB_KycStatus *kyc,
+ bool bad_kyc_auth)
{
return TALER_MHD_REPLY_JSON_PACK (
connection,
@@ -348,6 +350,18 @@ TEH_RESPONSE_reply_kyc_required (struct MHD_Connection
*connection,
TALER_JSON_pack_ec (TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED),
GNUNET_JSON_pack_data_auto ("h_payto",
h_payto),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_data_auto (
+ "account_pub",
+ (kyc->have_account_pub
+ ? &kyc->account_pub
+ : NULL))),
+ GNUNET_JSON_pack_allow_null (
+ bad_kyc_auth
+ ? GNUNET_JSON_pack_bool ("bad_kyc_auth",
+ bad_kyc_auth)
+ : GNUNET_JSON_pack_string ("bad_kyc_auth",
+ NULL)),
GNUNET_JSON_pack_uint64 ("requirement_row",
kyc->requirement_row));
}
diff --git a/src/exchange/taler-exchange-httpd_responses.h
b/src/exchange/taler-exchange-httpd_responses.h
index 77ca9d557..79f505538 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -89,12 +89,18 @@ TEH_RESPONSE_reply_reserve_age_restriction_required (
* @param connection connection to the client
* @param h_payto account identifier to include in reply
* @param kyc details about the KYC requirements
+ * @param bad_kyc_auth true if the target_pub of the
+ * @a h_payto account does not match the merchant_pub
+ * from the operation and thus a KYC AUTH transfer is
+ * required
* @return MHD result code
*/
MHD_RESULT
-TEH_RESPONSE_reply_kyc_required (struct MHD_Connection *connection,
- const struct TALER_PaytoHashP *h_payto,
- const struct TALER_EXCHANGEDB_KycStatus *kyc);
+TEH_RESPONSE_reply_kyc_required (
+ struct MHD_Connection *connection,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_EXCHANGEDB_KycStatus *kyc,
+ bool bad_kyc_auth);
/**
diff --git a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql
b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql
index 21d8735db..c1fc169fe 100644
--- a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql
+++ b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql
@@ -14,30 +14,50 @@
-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
--
-CREATE OR REPLACE FUNCTION exchange_do_trigger_kyc_rule_for_account(
+DROP FUNCTION IF EXISTS exchange_do_trigger_kyc_rule_for_account;
+
+CREATE FUNCTION exchange_do_trigger_kyc_rule_for_account(
IN in_h_payto BYTEA,
IN in_account_pub BYTEA, -- can be NULL
+ IN in_merchant_pub BYTEA, -- can be NULL
IN in_payto_uri TEXT, -- can be NULL
IN in_now INT8,
IN in_jmeasures TEXT,
IN in_display_priority INT4,
- OUT out_legitimization_measure_serial_id INT8)
+ OUT out_legitimization_measure_serial_id INT8,
+ OUT out_bad_kyc_auth BOOL)
LANGUAGE plpgsql
AS $$
DECLARE
+ my_rec RECORD;
my_access_token BYTEA;
+ my_account_pub BYTEA;
BEGIN
-- Note: in_payto_uri is allowed to be NULL *if*
-- in_h_payto is already in wire_targets
+
SELECT
- access_token
+ access_token
+ ,account_pub
INTO
- my_access_token
+ my_rec
FROM wire_targets
WHERE wire_target_h_payto=in_h_payto;
-IF NOT FOUND
+IF FOUND
THEN
+ -- Extract details, determine if KYC auth matches.
+ my_access_token = my_rec.access_token;
+ my_account_pub = my_rec.account_pub;
+ IF in_merchant_pub IS NULL
+ THEN
+ out_bad_kyc_auth = FALSE;
+ ELSE
+ out_bad_kyc_auth = (my_account_pub = in_merchant_pub);
+ END IF;
+ELSE
+ -- No constraint on merchant_pub, just create
+ -- the wire_target.
INSERT INTO wire_targets
(payto_uri
,wire_target_h_payto
@@ -49,6 +69,7 @@ THEN
RETURNING
access_token
INTO my_access_token;
+ out_bad_kyc_auth=TRUE;
END IF;
-- First check if a perfectly equivalent legi measure
diff --git a/src/exchangedb/pg_get_kyc_rules.c
b/src/exchangedb/pg_get_kyc_rules.c
index 34b06d366..67bebe9e7 100644
--- a/src/exchangedb/pg_get_kyc_rules.c
+++ b/src/exchangedb/pg_get_kyc_rules.c
@@ -30,6 +30,7 @@ enum GNUNET_DB_QueryStatus
TEH_PG_get_kyc_rules (
void *cls,
const struct TALER_PaytoHashP *h_payto,
+ union TALER_AccountPublicKeyP *account_pub,
json_t **jrules)
{
struct PostgresClosure *pg = cls;
@@ -41,16 +42,24 @@ TEH_PG_get_kyc_rules (
GNUNET_PQ_query_param_end
};
struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("target_pub",
+ account_pub),
TALER_PQ_result_spec_json ("jnew_rules",
jrules),
GNUNET_PQ_result_spec_end
};
+ memset (account_pub,
+ 0,
+ sizeof (*account_pub));
PREPARE (pg,
"get_kyc_rules",
"SELECT"
- " jnew_rules"
- " FROM legitimization_outcomes"
+ " wt.target_pub"
+ " ,lo.jnew_rules"
+ " FROM legitimization_outcomes lo"
+ " JOIN wire_targets wt"
+ " ON (lo.h_payto = wt.wire_target_h_payto)"
" WHERE h_payto=$1"
" AND expiration_time >= $2"
" AND is_active;");
diff --git a/src/exchangedb/pg_get_kyc_rules.h
b/src/exchangedb/pg_get_kyc_rules.h
index 9b0e2d68d..7f52b9a26 100644
--- a/src/exchangedb/pg_get_kyc_rules.h
+++ b/src/exchangedb/pg_get_kyc_rules.h
@@ -31,6 +31,8 @@
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param h_payto account identifier
+ * @param[out] account_pub account public key the rules
+ * apply to (because this key was used in KYC auth)
* @param[out] jrules set to the active KYC rules for the
* given account, set to NULL if no custom rules are active
* @return transaction status code
@@ -39,6 +41,7 @@ enum GNUNET_DB_QueryStatus
TEH_PG_get_kyc_rules (
void *cls,
const struct TALER_PaytoHashP *h_payto,
+ union TALER_AccountPublicKeyP *account_pub,
json_t **jrules);
#endif
diff --git a/src/exchangedb/pg_trigger_kyc_rule_for_account.c
b/src/exchangedb/pg_trigger_kyc_rule_for_account.c
index fc54d04f1..bc7b81a74 100644
--- a/src/exchangedb/pg_trigger_kyc_rule_for_account.c
+++ b/src/exchangedb/pg_trigger_kyc_rule_for_account.c
@@ -31,19 +31,24 @@ TEH_PG_trigger_kyc_rule_for_account (
void *cls,
const char *payto_uri,
const struct TALER_PaytoHashP *h_payto,
- const union TALER_AccountPublicKeyP *account_pub,
+ const union TALER_AccountPublicKeyP *set_account_pub,
+ const struct TALER_MerchantPublicKeyP *check_merchant_pub,
const json_t *jmeasures,
uint32_t display_priority,
- uint64_t *requirement_row)
+ uint64_t *requirement_row,
+ bool *bad_kyc_auth)
{
struct PostgresClosure *pg = cls;
struct GNUNET_TIME_Absolute now
= GNUNET_TIME_absolute_get ();
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (h_payto),
- NULL == account_pub
+ NULL == set_account_pub
? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_auto_from_type (account_pub),
+ : GNUNET_PQ_query_param_auto_from_type (set_account_pub),
+ NULL == check_merchant_pub
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_auto_from_type (check_merchant_pub),
NULL == payto_uri
? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_string (payto_uri),
@@ -56,6 +61,9 @@ TEH_PG_trigger_kyc_rule_for_account (
GNUNET_PQ_result_spec_uint64 (
"legitimization_measure_serial_id",
requirement_row),
+ GNUNET_PQ_result_spec_bool (
+ "bad_kyc_auth",
+ bad_kyc_auth),
GNUNET_PQ_result_spec_end
};
@@ -64,8 +72,10 @@ TEH_PG_trigger_kyc_rule_for_account (
"SELECT"
" out_legitimization_measure_serial_id"
" AS legitimization_measure_serial_id"
+ " ,out_bad_kyc_auth"
+ " AS bad_kyc_auth"
" FROM exchange_do_trigger_kyc_rule_for_account"
- "($1, $2, $3, $4, $5, $6);");
+ "($1, $2, $3, $4, $5, $6, $7);");
return GNUNET_PQ_eval_prepared_singleton_select (
pg->conn,
diff --git a/src/exchangedb/pg_trigger_kyc_rule_for_account.h
b/src/exchangedb/pg_trigger_kyc_rule_for_account.h
index 7c8db0445..56ee0ca8b 100644
--- a/src/exchangedb/pg_trigger_kyc_rule_for_account.h
+++ b/src/exchangedb/pg_trigger_kyc_rule_for_account.h
@@ -34,11 +34,16 @@
* can be NULL if @a h_payto is already
* guaranteed to be in wire_targets
* @param h_payto hash of @a payto_uri
- * @param account_pub public key to enable for the
+ * @param set_account_pub public key to enable for the
* KYC authorization, NULL if not known
+ * @param check_merchant_pub public key that must already
+ * be enabled for a KYC authorzation for it to be
+ * valid, NULL if not known
* @param jmeasures serialized MeasureSet to put in place
* @param display_priority priority of the rule
* @param[out] requirement_row set to legitimization requirement row for this
check
+ * @param[out] bad_kyc_auth set if @a check_account_pub
+ * did not match the existing KYC auth
* @return database transaction status
*/
enum GNUNET_DB_QueryStatus
@@ -46,9 +51,11 @@ TEH_PG_trigger_kyc_rule_for_account (
void *cls,
const char *payto_uri,
const struct TALER_PaytoHashP *h_payto,
- const union TALER_AccountPublicKeyP *account_pub,
+ const union TALER_AccountPublicKeyP *set_account_pub,
+ const struct TALER_MerchantPublicKeyP *check_merchant_pub,
const json_t *jmeasures,
uint32_t display_priority,
- uint64_t *requirement_row);
+ uint64_t *requirement_row,
+ bool *bad_kyc_auth);
#endif
diff --git a/src/include/taler_exchange_service.h
b/src/include/taler_exchange_service.h
index b9b1f8778..364c400f9 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -36,7 +36,7 @@
* Version of the Taler Exchange API, in hex.
* Thus 0.8.4-1 = 0x00080401.
*/
-#define TALER_EXCHANGE_API_VERSION 0x00100002
+#define TALER_EXCHANGE_API_VERSION 0x00100003
/**
* Information returned when a client needs to pass
@@ -63,6 +63,11 @@ struct TALER_EXCHANGE_KycNeededRedirect
*/
uint64_t requirement_row;
+ /**
+ * Set to true if the KYC AUTH public key known to the exchange does not
+ * match the merchant public key associated with the deposit operation.
+ */
+ bool bad_kyc_auth;
};
diff --git a/src/include/taler_exchangedb_plugin.h
b/src/include/taler_exchangedb_plugin.h
index 0b0e5fb0b..ae0d2d2b1 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -2957,12 +2957,25 @@ struct TALER_EXCHANGEDB_CsRevealFreshCoinData
*/
struct TALER_EXCHANGEDB_KycStatus
{
+
+ /**
+ * Account public key that is currently associated
+ * with the account. Only set if @e have_account_pub
+ * is true.
+ */
+ union TALER_AccountPublicKeyP account_pub;
+
/**
* Number that identifies the KYC requirement the operation
* was about.
*/
uint64_t requirement_row;
+ /**
+ * True if @e account_pub is set.
+ */
+ bool have_account_pub;
+
/**
* True if the KYC status is "satisfied".
*/
@@ -6898,11 +6911,16 @@ struct TALER_EXCHANGEDB_Plugin
* can be NULL if @a h_payto is already
* guaranteed to be in wire_targets
* @param h_payto hash of @a payto_uri
- * @param account_pub public key to enable for the
+ * @param set_account_pub public key to enable for the
* KYC authorization, NULL if not known
+ * @param check_merchant_pub public key that must already
+ * be enabled for a KYC authorzation for it to be
+ * valid, NULL if not known
* @param jmeasures serialized MeasureSet to put in place
* @param display_priority priority of the rule
* @param[out] requirement_row set to legitimization requirement row for
this check
+ * @param[out] bad_kyc_auth set if @a check_account_pub
+ * did not match the existing KYC auth
* @return database transaction status
*/
enum GNUNET_DB_QueryStatus
@@ -6910,10 +6928,12 @@ struct TALER_EXCHANGEDB_Plugin
void *cls,
const char *payto_uri,
const struct TALER_PaytoHashP *h_payto,
- const union TALER_AccountPublicKeyP *account_pub,
+ const union TALER_AccountPublicKeyP *set_account_pub,
+ const struct TALER_MerchantPublicKeyP *check_merchant_pub,
const json_t *jmeasures,
uint32_t display_priority,
- uint64_t *requirement_row);
+ uint64_t *requirement_row,
+ bool *bad_kyc_auth);
/**
@@ -7091,6 +7111,8 @@ struct TALER_EXCHANGEDB_Plugin
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param h_payto account identifier
+ * @param[out] account_pub account public key the rules
+ * apply to (because this key was used in KYC auth)
* @param[out] jrules set to the active KYC rules for the
* given account, set to NULL if no custom rules are active
* @return transaction status code
@@ -7099,6 +7121,7 @@ struct TALER_EXCHANGEDB_Plugin
(*get_kyc_rules)(
void *cls,
const struct TALER_PaytoHashP *h_payto,
+ union TALER_AccountPublicKeyP *account_pub,
json_t **jrules);
diff --git a/src/json/test_json.c b/src/json/test_json.c
index fba72f84b..4dac3bf79 100644
--- a/src/json/test_json.c
+++ b/src/json/test_json.c
@@ -76,9 +76,11 @@ path_cb (void *cls,
json_t *parent)
{
struct TestPath_Closure *cmp = cls;
+ unsigned int i;
+
if (NULL == cmp)
return;
- unsigned int i = cmp->results_length;
+ i = cmp->results_length;
if ((0 != strcmp (cmp->object_ids[i],
object_id)) ||
(1 != json_equal (cmp->parents[i],
diff --git a/src/lib/exchange_api_batch_deposit.c
b/src/lib/exchange_api_batch_deposit.c
index 8aa1bb83f..dd0f09380 100644
--- a/src/lib/exchange_api_batch_deposit.c
+++ b/src/lib/exchange_api_batch_deposit.c
@@ -473,6 +473,9 @@ handle_deposit_finished (void *cls,
GNUNET_JSON_spec_uint64 (
"requirement_row",
&dr->details.unavailable_for_legal_reasons.requirement_row),
+ GNUNET_JSON_spec_bool (
+ "bad_kyc_auth",
+ &dr->details.unavailable_for_legal_reasons.bad_kyc_auth),
GNUNET_JSON_spec_end ()
};
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.