gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

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