gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: work on #9053 (WiP)


From: gnunet
Subject: [taler-exchange] branch master updated: work on #9053 (WiP)
Date: Sun, 05 Jan 2025 17:10:42 +0100

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 975a36d70 work on #9053 (WiP)
975a36d70 is described below

commit 975a36d70b48ba6d337bacc7066f23d1d241580a
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jan 5 17:10:30 2025 +0100

    work on #9053 (WiP)
---
 debian/taler-exchange.install                 |   2 +
 doc/Makefile.am                               |   9 +-
 doc/prebuilt                                  |   2 +-
 src/exchange/.gitignore                       |   1 +
 src/exchange/Makefile.am                      |  16 +-
 src/exchange/taler-exchange-sanctionscheck.c  | 434 ++++++++++++++++++++++++++
 src/exchangedb/Makefile.am                    |   2 +
 src/exchangedb/pg_insert_sanction_list_hit.c  |  41 +++
 src/exchangedb/pg_insert_sanction_list_hit.h  |  53 ++++
 src/exchangedb/pg_select_all_kyc_attributes.c |  37 +++
 src/exchangedb/pg_select_all_kyc_attributes.h |  43 +++
 src/exchangedb/plugin_exchangedb_postgres.c   |   6 +
 src/include/taler_exchangedb_plugin.h         |  67 ++++
 src/include/taler_kyclogic_lib.h              |   8 +-
 src/kyclogic/kyclogic_sanctions.c             |  16 +-
 15 files changed, 719 insertions(+), 18 deletions(-)

diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
index 64c485e90..44b5e0d5b 100644
--- a/debian/taler-exchange.install
+++ b/debian/taler-exchange.install
@@ -22,6 +22,7 @@ usr/bin/taler-exchange-kyc-persona-converter.sh
 usr/bin/taler-exchange-kyc-tester
 usr/bin/taler-exchange-kyc-trigger
 usr/bin/taler-exchange-router
+usr/bin/taler-exchange-sanctionscheck
 usr/bin/taler-exchange-secmod-cs
 usr/bin/taler-exchange-secmod-eddsa
 usr/bin/taler-exchange-secmod-rsa
@@ -43,6 +44,7 @@ usr/share/man/man1/taler-exchange-kyc-aml-pep-trigger.1
 usr/share/man/man1/taler-exchange-kyc-tester.1
 usr/share/man/man1/taler-exchange-kyc-trigger.1
 usr/share/man/man1/taler-exchange-router.1
+usr/share/man/man1/taler-exchange-sanctionscheck.1
 usr/share/man/man1/taler-exchange-secmod-cs.1
 usr/share/man/man1/taler-exchange-secmod-eddsa.1
 usr/share/man/man1/taler-exchange-secmod-rsa.1
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 655723889..12728c943 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -30,20 +30,21 @@ man_MANS = \
   prebuilt/man/taler-exchange-kyc-trigger.1   \
   prebuilt/man/taler-exchange-offline.1       \
   prebuilt/man/taler-exchange-router.1        \
+  prebuilt/man/taler-exchange-sanctionscheck.1      \
   prebuilt/man/taler-exchange-secmod-cs.1     \
   prebuilt/man/taler-exchange-secmod-eddsa.1  \
   prebuilt/man/taler-exchange-secmod-rsa.1    \
   prebuilt/man/taler-exchange-transfer.1      \
-  prebuilt/man/taler-exchange-wire-gateway-client.1\
+  prebuilt/man/taler-exchange-wire-gateway-client.1 \
   prebuilt/man/taler-exchange-wirewatch.1     \
   prebuilt/man/taler-fakebank-run.1           \
-  prebuilt/man/taler-helper-auditor-aggregation.1 \
+  prebuilt/man/taler-helper-auditor-aggregation.1   \
   prebuilt/man/taler-helper-auditor-coins.1   \
   prebuilt/man/taler-helper-auditor-deposits.1\
   prebuilt/man/taler-helper-auditor-purses.1  \
   prebuilt/man/taler-helper-auditor-reserves.1\
-  prebuilt/man/taler-helper-auditor-wire-credit.1 \
-  prebuilt/man/taler-helper-auditor-wire-debit.1  \
+  prebuilt/man/taler-helper-auditor-wire-credit.1   \
+  prebuilt/man/taler-helper-auditor-wire-debit.1    \
   prebuilt/man/taler-terms-generator.1        \
   prebuilt/man/taler-unified-setup.1
 
diff --git a/doc/prebuilt b/doc/prebuilt
index b97d82f99..3b83e3fc9 160000
--- a/doc/prebuilt
+++ b/doc/prebuilt
@@ -1 +1 @@
-Subproject commit b97d82f99dc32b0fdb7942dbb501603a2c86f8b1
+Subproject commit 3b83e3fc98d4621b8792c61c6ec67d6bc41c4dd9
diff --git a/src/exchange/.gitignore b/src/exchange/.gitignore
index bcfdb7e82..5cb56ae35 100644
--- a/src/exchange/.gitignore
+++ b/src/exchange/.gitignore
@@ -11,3 +11,4 @@ taler-exchange-closer
 taler-exchange-transfer
 taler-exchange-router
 taler-exchange-expire
+taler-exchange-sanctionscheck
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index 2aa29e9f1..ae0291707 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -31,6 +31,7 @@ bin_PROGRAMS = \
   taler-exchange-expire \
   taler-exchange-httpd \
   taler-exchange-router \
+  taler-exchange-sanctionscheck \
   taler-exchange-transfer \
   taler-exchange-wirewatch
 
@@ -43,9 +44,9 @@ taler_exchange_aggregator_LDADD = \
   $(top_builddir)/src/util/libtalerutil.la \
   $(top_builddir)/src/bank-lib/libtalerbank.la \
   $(top_builddir)/src/exchangedb/libtalerexchangedb.la \
-  -ljansson \
   -lgnunetcurl \
   -lgnunetutil \
+  -ljansson \
   $(XLIB)
 
 
@@ -101,6 +102,19 @@ taler_exchange_router_LDADD = \
   -lgnunetutil \
   $(XLIB)
 
+taler_exchange_sanctionscheck_SOURCES = \
+  taler-exchange-sanctionscheck.c
+taler_exchange_sanctionscheck_LDADD = \
+  $(LIBGCRYPT_LIBS) \
+  $(top_builddir)/src/kyclogic/libtalerkyclogic.la \
+  $(top_builddir)/src/json/libtalerjson.la \
+  $(top_builddir)/src/util/libtalerutil.la \
+  $(top_builddir)/src/exchangedb/libtalerexchangedb.la \
+  -lgnunetjson \
+  -ljansson \
+  -lgnunetutil \
+  $(XLIB)
+
 taler_exchange_transfer_SOURCES = \
   taler-exchange-transfer.c
 taler_exchange_transfer_LDADD = \
diff --git a/src/exchange/taler-exchange-sanctionscheck.c 
b/src/exchange/taler-exchange-sanctionscheck.c
new file mode 100644
index 000000000..40df83ea6
--- /dev/null
+++ b/src/exchange/taler-exchange-sanctionscheck.c
@@ -0,0 +1,434 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2025 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
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-sanctionscheck.c
+ * @brief Process that checks all existing customers against a sanctions list
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include <pthread.h>
+#include <microhttpd.h>
+#include "taler_exchangedb_lib.h"
+#include "taler_exchangedb_plugin.h"
+#include "taler_json_lib.h"
+#include "taler_kyclogic_lib.h"
+
+
+/**
+ * Account we are currently checking.
+ */
+struct Account
+{
+  /**
+   * Kept in a DLL.
+   */
+  struct Account *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct Account *prev;
+
+  /**
+   * Original properties of the account.
+   */
+  json_t *properties;
+
+  /**
+   * Evaluation entry with the sanction list checker.
+   */
+  struct TALER_KYCLOGIC_EvaluationEntry *ee;
+
+  /**
+   * Row of the attributes in the kyc_attributes table.
+   */
+  uint64_t row_id;
+
+  /**
+   * Hash of the normalized payto:// URI of the account.
+   */
+  struct TALER_NormalizedPaytoHashP h_payto;
+
+};
+
+
+/**
+ * The exchange's configuration (global)
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Our DB plugin.
+ */
+static struct TALER_EXCHANGEDB_Plugin *db_plugin;
+
+/**
+ * Helper process for the actual rating.
+ */
+static struct TALER_KYCLOGIC_SanctionRater *sr;
+
+/**
+ * Value to return from main(). 0 on success, non-zero on
+ * on serious errors.
+ */
+static int global_ret;
+
+/**
+ * Key used to encrypt KYC attribute data in our database.
+ */
+static struct TALER_AttributeEncryptionKeyP attribute_key;
+
+/**
+ * Account rules to set if we have a good match against the
+ * sanction list and should freeze an account immediately.
+ */
+static json_t *freeze_rules;
+
+/**
+ * Head of DLL of accounts we are currently checking.
+ */
+static struct Account *acc_head;
+
+/**
+ * Tail of DLL of accounts we are currently checking.
+ */
+static struct Account *acc_tail;
+
+
+/**
+ * We're being aborted with CTRL-C (or SIGTERM). Shut down.
+ *
+ * @param cls closure
+ */
+static void
+shutdown_task (void *cls)
+{
+  struct Account *acc;
+
+  (void) cls;
+  while (NULL != (acc = acc_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (acc_head,
+                                 acc_tail,
+                                 acc);
+    json_decref (acc->properties);
+    GNUNET_free (acc);
+  }
+
+  if (NULL != sr)
+  {
+    TALER_KYCLOGIC_sanction_rater_stop (sr);
+    sr = NULL;
+  }
+  TALER_EXCHANGEDB_plugin_unload (db_plugin);
+  db_plugin = NULL;
+  cfg = NULL;
+}
+
+
+/**
+ * Function called with the result of a sanction evaluation.
+ *
+ * @param cls closure
+ * @param ec error code, #TALER_EC_NONE on success
+ * @param best_match identifies the sanction list entry with the best match
+ * @param rating likelihood of the match, from 0 (none) to 1 (perfect)
+ * @param confidence confidence in the evaluation, from 0 (none) to 1 (perfect)
+ */
+static void
+sanction_cb (void *cls,
+             enum TALER_ErrorCode ec,
+             const char *best_match,
+             double rating,
+             double confidence)
+{
+  struct Account *acc = cls;
+  bool freeze = false;
+  bool investigate = false;
+
+  // FIXME-#9053: formulas to be improved and customized via configuration
+  if ( (rating > 0.95) &&
+       (confidence > 0.95) )
+  {
+    freeze = true;
+    investigate = true;
+  }
+  else if (rating > 0.95 - confidence)
+  {
+    investigate = true;
+  }
+  if (freeze || investigate)
+  {
+    static const char *freeze_event[] = {
+      "sanction-list-hit-account-frozen",
+    };
+    static const char *partial_match_event[] = {
+      "sanction-list-hit-partial-account-investigated",
+    };
+    enum GNUNET_DB_QueryStatus qs;
+    json_t *properties;
+    const char **events;
+    json_t *new_rules;
+
+    new_rules = freeze ? freeze_rules : NULL;
+    events = freeze ? freeze_event : partial_match_event;
+    properties = GNUNET_JSON_PACK (
+      GNUNET_JSON_pack_string ("sanction_list_best_match",
+                               best_match),
+      GNUNET_JSON_pack_double ("sanction_list_rating",
+                               rating),
+      GNUNET_JSON_pack_double ("sanction_list_confidence",
+                               confidence));
+    GNUNET_assert (0 ==
+                   json_object_update_missing (properties,
+                                               acc->properties));
+    qs = db_plugin->insert_sanction_list_hit (db_plugin->cls,
+                                              &acc->h_payto,
+                                              investigate,
+                                              new_rules,
+                                              properties,
+                                              1,
+                                              events);
+    json_decref (properties);
+    if (qs < 0)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Failed to insert sanction list evaluation result\n");
+      global_ret = EXIT_FAILURE;
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+  }
+  GNUNET_CONTAINER_DLL_remove (acc_head,
+                               acc_tail,
+                               acc);
+  json_decref (acc->properties);
+  GNUNET_free (acc);
+  if (NULL != acc_head)
+    return; /* more work */
+  {
+    enum GNUNET_DB_QueryStatus qs;
+
+    qs = db_plugin->commit (db_plugin->cls);
+    if (qs < 0)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Failed to commit DB transaction\n");
+      global_ret = EXIT_NOTCONFIGURED;
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+  }
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Function called on each account.
+ *
+ * @param cls closure
+ * @param row_id row of the attributes in the database
+ * @param h_payto account for which the attribute data is stored
+ * @param provider_name provider that must be checked
+ * @param collection_time when was the data collected
+ * @param expiration_time when does the data expire
+ * @param properties properties that were set for @a h_payto
+ * @param enc_attributes_size number of bytes in @a enc_attributes
+ * @param enc_attributes encrypted attribute data
+ * @return true to continue to iterate
+ */
+static bool
+account_cb (void *cls,
+            uint64_t row_id,
+            const struct TALER_NormalizedPaytoHashP *h_payto,
+            const char *provider_name,
+            struct GNUNET_TIME_Timestamp collection_time,
+            struct GNUNET_TIME_Timestamp expiration_time,
+            const json_t *properties,
+            size_t enc_attributes_size,
+            const void *enc_attributes)
+{
+  json_t *attributes;
+  struct Account *acc;
+
+  (void) cls;
+  /* FIXME-#9053: GANA-ize the property key */
+  if (json_boolean_value (json_object_get (properties,
+                                           "sanction-list-suppress")))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Skipping %llu as suppressed by staff as false-positive\n",
+                (unsigned long long) row_id);
+    return true;
+  }
+  attributes = TALER_CRYPTO_kyc_attributes_decrypt (&attribute_key,
+                                                    enc_attributes,
+                                                    enc_attributes_size);
+  if (NULL == attributes)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to decrypt attributes at row #%llu\n",
+                (unsigned long long) row_id);
+    return true;
+  }
+  acc = GNUNET_new (struct Account);
+  acc->row_id = row_id;
+  acc->h_payto = *h_payto;
+  acc->properties = json_incref ((json_t *) properties);
+  acc->ee = TALER_KYCLOGIC_sanction_rater_eval (sr,
+                                                attributes,
+                                                &sanction_cb,
+                                                acc);
+  if (NULL == acc->ee)
+  {
+    GNUNET_free (acc);
+    return false;
+  }
+  GNUNET_CONTAINER_DLL_insert (acc_head,
+                               acc_tail,
+                               acc);
+  return true;
+}
+
+
+/**
+ * First task.
+ *
+ * @param cls closure, NULL
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
+ * @param c configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  enum GNUNET_DB_QueryStatus qs;
+
+  (void) cls;
+  (void) args;
+  (void) cfgfile;
+  cfg = c;
+
+  {
+    char *attr_enc_key_str;
+
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_string (cfg,
+                                               "exchange",
+                                               "ATTRIBUTE_ENCRYPTION_KEY",
+                                               &attr_enc_key_str))
+    {
+      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                                 "exchange",
+                                 "ATTRIBUTE_ENCRYPTION_KEY");
+      global_ret = EXIT_NOTCONFIGURED;
+      return;
+    }
+    GNUNET_CRYPTO_hash (attr_enc_key_str,
+                        strlen (attr_enc_key_str),
+                        &attribute_key.hash);
+    GNUNET_free (attr_enc_key_str);
+  }
+  if (NULL ==
+      (db_plugin = TALER_EXCHANGEDB_plugin_load (cfg,
+                                                 false)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to initialize DB subsystem\n");
+    global_ret = EXIT_NOTCONFIGURED;
+    return;
+  }
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                 cls);
+  sr = TALER_KYCLOGIC_sanction_rater_start (args[0],
+                                            args);
+  if (NULL == sr)
+  {
+    global_ret = EXIT_INVALIDARGUMENT;
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_OK !=
+      db_plugin->start (db_plugin->cls,
+                        "sanctionscheck"))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to begin DB transaction\n");
+    global_ret = EXIT_NOTCONFIGURED;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  qs = db_plugin->select_all_kyc_attributes (db_plugin->cls,
+                                             &account_cb,
+                                             NULL);
+  if (qs < 0)
+  {
+    global_ret = EXIT_FAILURE;
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+  {
+    db_plugin->rollback (db_plugin->cls);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GNUNET_assert (NULL != acc_head);
+}
+
+
+/**
+ * The main function of taler-exchange-sanctionscheck
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, non-zero on error
+ */
+int
+main (int argc,
+      char *const *argv)
+{
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_version (VERSION "-" VCS_VERSION),
+    GNUNET_GETOPT_OPTION_END
+  };
+  enum GNUNET_GenericReturnValue ret;
+
+  freeze_rules = NULL; /* FIXME-#9053: set to JSON rules that freeze the 
account */
+  ret = GNUNET_PROGRAM_run (
+    TALER_EXCHANGE_project_data (),
+    argc, argv,
+    "taler-exchange-sanctionscheck",
+    gettext_noop (
+      "process that checks all existing customer accounts against a sanctions 
list"),
+    options,
+    &run, NULL);
+  if (GNUNET_SYSERR == ret)
+    return EXIT_INVALIDARGUMENT;
+  if (GNUNET_NO == ret)
+    return EXIT_SUCCESS;
+  return global_ret;
+}
+
+
+/* end of taler-exchange-sanctionscheck.c */
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 7e66aa879..5f3c5bf3d 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -219,6 +219,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
   pg_insert_refund.h pg_insert_refund.c \
   pg_insert_reserve_closed.h pg_insert_reserve_closed.c \
   pg_insert_reserve_open_deposit.c pg_insert_reserve_open_deposit.h \
+  pg_insert_sanction_list_hit.h pg_insert_sanction_list_hit.c \
   pg_insert_signkey_revocation.h pg_insert_signkey_revocation.c \
   pg_insert_successor_measure.h pg_insert_successor_measure.c \
   pg_insert_wire.h pg_insert_wire.c \
@@ -270,6 +271,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
   pg_select_aggregation_amounts_for_kyc_check.h 
pg_select_aggregation_amounts_for_kyc_check.c \
   pg_select_aggregation_transient.h pg_select_aggregation_transient.c \
   pg_select_aggregations_above_serial.h pg_select_aggregations_above_serial.c \
+  pg_select_all_kyc_attributes.h pg_select_all_kyc_attributes.c \
   pg_select_all_purse_decisions_above_serial_id.h 
pg_select_all_purse_decisions_above_serial_id.c \
   pg_select_all_purse_deletions_above_serial_id.h 
pg_select_all_purse_deletions_above_serial_id.c \
   pg_select_aml_attributes.h pg_select_aml_attributes.c \
diff --git a/src/exchangedb/pg_insert_sanction_list_hit.c 
b/src/exchangedb/pg_insert_sanction_list_hit.c
new file mode 100644
index 000000000..fa8380f9c
--- /dev/null
+++ b/src/exchangedb/pg_insert_sanction_list_hit.c
@@ -0,0 +1,41 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2025 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file exchangedb/pg_insert_sanction_list_hit.c
+ * @brief Implementation of the insert_sanction_list_hit function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_insert_sanction_list_hit.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_insert_sanction_list_hit (
+  void *cls,
+  const struct TALER_NormalizedPaytoHashP *h_payto,
+  bool to_investigate,
+  const json_t *new_rules,
+  const json_t *account_properties,
+  unsigned int num_events,
+  const char **events)
+{
+  GNUNET_break (0); // FIXME-#9053: not implemented
+  return -2;
+}
diff --git a/src/exchangedb/pg_insert_sanction_list_hit.h 
b/src/exchangedb/pg_insert_sanction_list_hit.h
new file mode 100644
index 000000000..3dc425a74
--- /dev/null
+++ b/src/exchangedb/pg_insert_sanction_list_hit.h
@@ -0,0 +1,53 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2025 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file exchangedb/pg_insert_sanction_list_hit.h
+ * @brief implementation of the insert_sanction_list_hit function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_INSERT_SANCTION_LIST_HIT_H
+#define PG_INSERT_SANCTION_LIST_HIT_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Update sanction list hit status of the given account.
+ *
+ * @param cls closure
+ * @param h_payto account for which the hit is to be stored
+ * @param to_investigate true to flag account for investigation,
+ *        false to **preserve** existing status
+ * @param new_rules new KYC rules to apply to the account, NULL to preserve
+ *        existing rules
+ * @param account_properties new account properties
+ * @param num_events length of the @a events array
+ * @param events array of KYC events to trigger
+ * @return database transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_insert_sanction_list_hit (
+  void *cls,
+  const struct TALER_NormalizedPaytoHashP *h_payto,
+  bool to_investigate,
+  const json_t *new_rules,
+  const json_t *account_properties,
+  unsigned int num_events,
+  const char **events);
+
+#endif
diff --git a/src/exchangedb/pg_select_all_kyc_attributes.c 
b/src/exchangedb/pg_select_all_kyc_attributes.c
new file mode 100644
index 000000000..cb0a652ae
--- /dev/null
+++ b/src/exchangedb/pg_select_all_kyc_attributes.c
@@ -0,0 +1,37 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2025 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file exchangedb/pg_select_all_kyc_attributes.c
+ * @brief Implementation of the select_all_kyc_attributes function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_all_kyc_attributes.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_all_kyc_attributes (
+  void *cls,
+  TALER_EXCHANGEDB_AllAttributesCallback cb,
+  void *cb_cls)
+{
+  GNUNET_break (0); // FIXME-#9053: not implemented
+  return -2;
+}
diff --git a/src/exchangedb/pg_select_all_kyc_attributes.h 
b/src/exchangedb/pg_select_all_kyc_attributes.h
new file mode 100644
index 000000000..5e876209a
--- /dev/null
+++ b/src/exchangedb/pg_select_all_kyc_attributes.h
@@ -0,0 +1,43 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2025 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file exchangedb/pg_select_all_kyc_attributes.h
+ * @brief implementation of the select_all_kyc_attributes function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_SELECT_ALL_KYC_ATTRIBUTES_H
+#define PG_SELECT_ALL_KYC_ATTRIBUTES_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Lookup all KYC attributes.
+ *
+ * @param cls closure
+ * @param cb callback to invoke on each match
+ * @param cb_cls closure for @a cb
+ * @return database transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_all_kyc_attributes (
+  void *cls,
+  TALER_EXCHANGEDB_AllAttributesCallback cb,
+  void *cb_cls);
+
+#endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 5c0bba422..132bf4c6a 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -123,6 +123,7 @@
 #include "pg_insert_refund.h"
 #include "pg_insert_reserve_closed.h"
 #include "pg_insert_reserve_open_deposit.h"
+#include "pg_insert_sanction_list_hit.h"
 #include "pg_insert_signkey_revocation.h"
 #include "pg_insert_successor_measure.h"
 #include "pg_insert_wire.h"
@@ -174,6 +175,7 @@
 #include "pg_select_aggregation_amounts_for_kyc_check.h"
 #include "pg_select_aggregation_transient.h"
 #include "pg_select_aggregations_above_serial.h"
+#include "pg_select_all_kyc_attributes.h"
 #include "pg_select_all_purse_decisions_above_serial_id.h"
 #include "pg_select_all_purse_deletions_above_serial_id.h"
 #include "pg_select_aml_attributes.h"
@@ -721,6 +723,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     = &TEH_PG_lookup_signing_key;
   plugin->lookup_h_payto_by_access_token
     = &TEH_PG_lookup_h_payto_by_access_token;
+  plugin->insert_sanction_list_hit
+    = &TEH_PG_insert_sanction_list_hit;
+  plugin->select_all_kyc_attributes
+    = &TEH_PG_select_all_kyc_attributes;
   plugin->begin_shard
     = &TEH_PG_begin_shard;
   plugin->abort_shard
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index c1eb5dd64..70c827a96 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -3670,6 +3670,33 @@ typedef void
   const void *enc_attributes);
 
 
+/**
+ * Return KYC attribute information.
+ *
+ * @param cls closure
+ * @param row_id current row in kyc_attributes table
+ * @param h_payto account the attributes are about
+ * @param provider_name name of the provider that collected the attributes
+ * @param collection_time when were the attributes collected
+ * @param expiration_time when does the data expire
+ * @param properties properties that were set for @a h_payto
+ * @param enc_attributes_size size of @a enc_attributes
+ * @param enc_attributes the encrypted collected attributes
+ * @return true to continue to iterate
+ */
+typedef bool
+(*TALER_EXCHANGEDB_AllAttributesCallback)(
+  void *cls,
+  uint64_t row_id,
+  const struct TALER_NormalizedPaytoHashP *h_payto,
+  const char *provider_name,
+  struct GNUNET_TIME_Timestamp collection_time,
+  struct GNUNET_TIME_Timestamp expiration_time,
+  const json_t *properties,
+  size_t enc_attributes_size,
+  const void *enc_attributes);
+
+
 /**
  * @brief The plugin API, returned from the plugin's "init" function.
  * The argument given to "init" is simply a configuration handle.
@@ -7353,6 +7380,31 @@ struct TALER_EXCHANGEDB_Plugin
     const char **events);
 
 
+  /**
+   * Update sanction list hit status of the given account.
+   *
+   * @param cls closure
+   * @param h_payto account for which the hit is to be stored
+   * @param to_investigate true to flag account for investigation,
+   *        false to **preserve** existing status
+   * @param new_rules new KYC rules to apply to the account, NULL to preserve
+   *        existing rules
+   * @param account_properties new account properties
+   * @param num_events length of the @a events array
+   * @param events array of KYC events to trigger
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+    (*insert_sanction_list_hit)(
+    void *cls,
+    const struct TALER_NormalizedPaytoHashP *h_payto,
+    bool to_investigate,
+    const json_t *new_rules,
+    const json_t *account_properties,
+    unsigned int num_events,
+    const char **events);
+
+
   /**
    * Update AML program status to finished (and failed).
    *
@@ -7403,6 +7455,21 @@ struct TALER_EXCHANGEDB_Plugin
     void *cb_cls);
 
 
+  /**
+   * Lookup all KYC attributes.
+   *
+   * @param cls closure
+   * @param cb callback to invoke on each match
+   * @param cb_cls closure for @a cb
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+    (*select_all_kyc_attributes)(
+    void *cls,
+    TALER_EXCHANGEDB_AllAttributesCallback cb,
+    void *cb_cls);
+
+
   /**
    * Lookup legitimization measures.
    *
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
index ab703fef6..360c57a84 100644
--- a/src/include/taler_kyclogic_lib.h
+++ b/src/include/taler_kyclogic_lib.h
@@ -1163,9 +1163,9 @@ typedef void
  * @return handle for sanction list rating
  */
 struct TALER_KYCLOGIC_SanctionRater *
-TALER_KYCLOGIC_saction_rater_start (
+TALER_KYCLOGIC_sanction_rater_start (
   const char *binary,
-  const char **argv);
+  char *const*argv);
 
 
 /**
@@ -1183,7 +1183,7 @@ struct TALER_KYCLOGIC_EvaluationEntry;
  * @return NULL on error
  */
 struct TALER_KYCLOGIC_EvaluationEntry *
-TALER_KYCLOGIC_saction_rater_eval (
+TALER_KYCLOGIC_sanction_rater_eval (
   struct TALER_KYCLOGIC_SanctionRater *sr,
   const json_t *attributes,
   TALER_KYCLOGIC_SanctionResultCallback cb,
@@ -1196,7 +1196,7 @@ TALER_KYCLOGIC_saction_rater_eval (
  * @param[in] sr process to stop
  */
 void
-TALER_KYCLOGIC_saction_rater_stop (
+TALER_KYCLOGIC_sanction_rater_stop (
   struct TALER_KYCLOGIC_SanctionRater *sr);
 
 #endif
diff --git a/src/kyclogic/kyclogic_sanctions.c 
b/src/kyclogic/kyclogic_sanctions.c
index 71e07e31a..018ddfe72 100644
--- a/src/kyclogic/kyclogic_sanctions.c
+++ b/src/kyclogic/kyclogic_sanctions.c
@@ -163,7 +163,7 @@ fail_hard (struct TALER_KYCLOGIC_SanctionRater *sr)
                                  sr->ee_tail,
                                  ee);
     ee->cb (ee->cb_cls,
-            /* FIXME: better EC? */
+            /* FIXME-#9053: better EC? */
             TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
             NULL,
             1.0,
@@ -428,8 +428,8 @@ child_done_cb (void *cls,
 
 
 struct TALER_KYCLOGIC_SanctionRater *
-TALER_KYCLOGIC_saction_rater_start (const char *binary,
-                                    const char **argv)
+TALER_KYCLOGIC_sanction_rater_start (const char *binary,
+                                     char *const*argv)
 {
   struct TALER_KYCLOGIC_SanctionRater *sr;
   struct GNUNET_DISK_PipeHandle *pipe_stdin;
@@ -482,10 +482,10 @@ TALER_KYCLOGIC_saction_rater_start (const char *binary,
 
 
 struct TALER_KYCLOGIC_EvaluationEntry *
-TALER_KYCLOGIC_saction_rater_eval (struct TALER_KYCLOGIC_SanctionRater *sr,
-                                   const json_t *attributes,
-                                   TALER_KYCLOGIC_SanctionResultCallback cb,
-                                   void *cb_cls)
+TALER_KYCLOGIC_sanction_rater_eval (struct TALER_KYCLOGIC_SanctionRater *sr,
+                                    const json_t *attributes,
+                                    TALER_KYCLOGIC_SanctionResultCallback cb,
+                                    void *cb_cls)
 {
   struct TALER_KYCLOGIC_EvaluationEntry *ee;
 
@@ -514,7 +514,7 @@ TALER_KYCLOGIC_saction_rater_eval (struct 
TALER_KYCLOGIC_SanctionRater *sr,
 
 
 void
-TALER_KYCLOGIC_saction_rater_stop (
+TALER_KYCLOGIC_sanction_rater_stop (
   struct TALER_KYCLOGIC_SanctionRater *sr)
 {
   fail_hard (sr);

-- 
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]