gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: -implement DB triggers and chec


From: gnunet
Subject: [taler-anastasis] branch master updated: -implement DB triggers and check for inbound wire transfers in IBAN plugin
Date: Thu, 19 Aug 2021 13:41:33 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 81d0e57  -implement DB triggers and check for inbound wire transfers 
in IBAN plugin
81d0e57 is described below

commit 81d0e570be0db784e98fdb7ad63f9b65c6745be3
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Aug 19 13:41:30 2021 +0200

    -implement DB triggers and check for inbound wire transfers in IBAN plugin
---
 src/authorization/Makefile.am                      |   3 +-
 .../anastasis-helper-authorization-iban.c          |  50 +++++++-
 .../anastasis_authorization_plugin_iban.c          | 134 ++++++++++++++++++++-
 src/authorization/iban.c                           |  43 +++++++
 src/authorization/iban.h                           |   2 +-
 5 files changed, 224 insertions(+), 8 deletions(-)

diff --git a/src/authorization/Makefile.am b/src/authorization/Makefile.am
index c2ae0a5..0687129 100644
--- a/src/authorization/Makefile.am
+++ b/src/authorization/Makefile.am
@@ -15,7 +15,7 @@ pkgdata_DATA = \
 
 EXTRA_DIST = \
   $(pkgdata_DATA) \
-  iban.h
+  iban.h iban.c
 
 
 if USE_COVERAGE
@@ -32,6 +32,7 @@ anastasis_helper_authorization_iban_LDADD = \
   $(top_builddir)/src/stasis/libanastasisdb.la \
   $(top_builddir)/src/authorization/libanastasiseufin/libanastasiseufin.la \
   $(top_builddir)/src/util/libanastasisutil.la \
+  -ltalermhd \
   -ltalerutil \
   -lgnunetcurl \
   -lgnunetutil \
diff --git a/src/authorization/anastasis-helper-authorization-iban.c 
b/src/authorization/anastasis-helper-authorization-iban.c
index 0d3200a..d509c0e 100644
--- a/src/authorization/anastasis-helper-authorization-iban.c
+++ b/src/authorization/anastasis-helper-authorization-iban.c
@@ -17,10 +17,6 @@
  * @file anastasis-helper-authorization-iban.c
  * @brief Process that watches for wire transfers to Anastasis bank account
  * @author Christian Grothoff
- *
- * TODO:
- * - needs to add DB triggers to notify main service of inbound activity
- * - needs man page
  */
 #include "platform.h"
 #include "anastasis_eufin_lib.h"
@@ -31,6 +27,7 @@
 #include <jansson.h>
 #include <pthread.h>
 #include <microhttpd.h>
+#include "iban.h"
 
 /**
  * How long to wait for an HTTP reply if there
@@ -107,6 +104,37 @@ static int test_mode;
 static struct GNUNET_SCHEDULER_Task *task;
 
 
+/**
+ * Notify anastasis-http that we received @a amount
+ * from @a sender_account_uri with @a code.
+ *
+ * @param sender_account_uri payto:// URI of the sending account
+ * @param code numeric code used in the wire transfer subject
+ * @param amount the amount that was wired
+ */
+static void
+notify (const char *sender_account_uri,
+        uint64_t code,
+        const struct TALER_Amount *amount)
+{
+  struct IbanEventP ev = {
+    .header.type = htons (TALER_DBEVENT_ANASTASIS_AUTH_IBAN_TRANSFER),
+    .header.size = htons (sizeof (ev)),
+    .code = GNUNET_htonll (code)
+  };
+  const char *as;
+
+  GNUNET_CRYPTO_hash (sender_account_uri,
+                      strlen (sender_account_uri),
+                      &ev.debit_iban_hash);
+  as = TALER_amount2s (amount);
+  db_plugin->event_notify (db_plugin->cls,
+                           &ev.header,
+                           as,
+                           strlen (as));
+}
+
+
 /**
  * We're being aborted with CTRL-C (or SIGTERM). Shut down.
  *
@@ -152,6 +180,9 @@ static void
 find_transfers (void *cls);
 
 
+#include "iban.c"
+
+
 /**
  * Callbacks of this type are used to serve the result of asking
  * the bank for the transaction history.
@@ -232,6 +263,17 @@ history_cb (void *cls,
     break;
   }
   latest_row_off = serial_id;
+  {
+    uint64_t code;
+
+    if (GNUNET_OK !=
+        extract_code (details->wire_subject,
+                      &code))
+      return GNUNET_OK;
+    notify (details->debit_account_uri,
+            code,
+            &details->amount);
+  }
   return GNUNET_OK;
 }
 
diff --git a/src/authorization/anastasis_authorization_plugin_iban.c 
b/src/authorization/anastasis_authorization_plugin_iban.c
index eee8e7e..4f43d3f 100644
--- a/src/authorization/anastasis_authorization_plugin_iban.c
+++ b/src/authorization/anastasis_authorization_plugin_iban.c
@@ -28,6 +28,16 @@
 #include "anastasis_util_lib.h"
 #include "iban.h"
 
+/**
+ * How long is a code valid once generated? Very long
+ * here as we do not want to refuse authentication
+ * just because the user took a while to execute the
+ * wire transfer (and then get back to their recovery
+ * operation).
+ */
+#define CODE_VALIDITY_PERIOD GNUNET_TIME_UNIT_MONTHS
+
+
 /**
  * Saves the State of a authorization plugin.
  */
@@ -367,7 +377,116 @@ respond_with_challenge (struct 
ANASTASIS_AUTHORIZATION_State *as,
       return ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED;
     return ANASTASIS_AUTHORIZATION_RES_SUCCESS;
   }
+}
+
+
+#include "iban.c"
+
+
+/**
+ * Check if the @a wire_subject matches the challenge in the context
+ * and if the @a amount is sufficient. If so, return true.
+ *
+ * @param cls a `const struct ANASTASIS_AUTHORIZATION_State *`
+ * @param amount the amount that was transferred
+ * @param wire_subject a wire subject we received
+ * @return true if the wire transfer satisfied the check
+ */
+static bool
+check_payment_ok (void *cls,
+                  const struct TALER_Amount *amount,
+                  const char *wire_subject)
+{
+  const struct ANASTASIS_AUTHORIZATION_State *as = cls;
+  struct IBAN_Context *ctx = as->ctx;
+  uint64_t code;
+
+  if (GNUNET_OK !=
+      extract_code (wire_subject,
+                    &code))
+    return false;
+  if (GNUNET_OK !=
+      TALER_amount_cmp_currency (&ctx->expected_amount,
+                                 amount))
+  {
+    /* currency wrong!? */
+    GNUNET_break (0);
+    return false;
+  }
+  if (1 ==
+      TALER_amount_cmp (&ctx->expected_amount,
+                        amount))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Amount `%s' insufficient for authorization\n",
+                TALER_amount2s (amount));
+    return false;
+  }
+  return (code == as->code);
+}
+
 
+/**
+ * Check if we have received a wire transfer with a subject
+ * authorizing the disclosure of the credential in the meantime.
+ *
+ * @param as state to check for
+ * @return WTS_SUCCESS if a transfer was received,
+ *         WTS_NOT_READY if no transfer was received,
+ *         WTS_FAILED_WITH_REPLY if we had an internal error and queued a reply
+ *         WTS_FAILED_WITHOUT_REPLY if we had an internal error and failed to 
queue a reply
+ */
+static enum
+{
+  WTS_SUCCESS,
+  WTS_NOT_READY,
+  WTS_FAILED_WITH_REPLY,
+  WTS_FAILED_WITHOUT_REPLY
+}
+test_wire_transfers (struct ANASTASIS_AUTHORIZATION_State *as)
+{
+  struct IBAN_Context *ctx = as->ctx;
+  struct ANASTASIS_DatabasePlugin *db = ctx->ac->db;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_TIME_Absolute now;
+  struct GNUNET_TIME_Absolute limit;
+  char *debit_account_uri;
+
+  now = GNUNET_TIME_absolute_get ();
+  limit = GNUNET_TIME_absolute_subtract (now,
+                                         CODE_VALIDITY_PERIOD);
+  GNUNET_asprintf (&debit_account_uri,
+                   "payto://iban/%s",
+                   as->iban_number);
+  qs = db->test_auth_iban_payment (
+    db->cls,
+    debit_account_uri,
+    limit,
+    &check_payment_ok,
+    as);
+  GNUNET_free (debit_account_uri);
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    return (MHD_YES ==
+            TALER_MHD_reply_with_error (as->connection,
+                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                        NULL))
+      ? WTS_FAILED_WITH_REPLY
+      : WTS_FAILED_WITHOUT_REPLY;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    return WTS_NOT_READY;
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+    break;
+  }
+  qs = db->mark_challenge_code_satisfied (
+    db->cls,
+    &as->truth_uuid,
+    as->code);
+  GNUNET_break (qs > 0);
+  return WTS_SUCCESS;
 }
 
 
@@ -423,6 +542,17 @@ iban_process (struct ANASTASIS_AUTHORIZATION_State *as,
       return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED;
     return ANASTASIS_AUTHORIZATION_RES_FAILED;
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    switch (test_wire_transfers (as))
+    {
+    case WTS_SUCCESS:
+      return ANASTASIS_AUTHORIZATION_RES_FINISHED;
+    case WTS_NOT_READY:
+      break;   /* continue below */
+    case WTS_FAILED_WITH_REPLY:
+      return ANASTASIS_AUTHORIZATION_RES_FAILED;
+    case WTS_FAILED_WITHOUT_REPLY:
+      return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED;
+    }
     if (GNUNET_TIME_absolute_is_future (timeout))
     {
       as->connection = connection;
@@ -529,9 +659,9 @@ libanastasis_plugin_authorization_iban_init (void *cls)
   ctx->ac = ac;
   plugin = GNUNET_new (struct ANASTASIS_AuthorizationPlugin);
   plugin->payment_plugin_managed = true;
-  plugin->code_validity_period = GNUNET_TIME_UNIT_MONTHS;
+  plugin->code_validity_period = CODE_VALIDITY_PERIOD;
   plugin->code_rotation_period = GNUNET_TIME_UNIT_WEEKS;
-  plugin->code_retransmission_frequency = GNUNET_TIME_UNIT_FOREVER_REL;
+  plugin->code_retransmission_frequency = GNUNET_TIME_UNIT_FOREVER_REL; /* not 
applicable */
   plugin->cls = ctx;
   plugin->validate = &iban_validate;
   plugin->start = &iban_start;
diff --git a/src/authorization/iban.c b/src/authorization/iban.c
new file mode 100644
index 0000000..9547790
--- /dev/null
+++ b/src/authorization/iban.c
@@ -0,0 +1,43 @@
+/**
+ * Extract a numeric @a code from a @a wire_subject.
+ * Also checks that the @a wire_subject contains the
+ * string "anastasis".
+ *
+ * @param wire_subject wire subject to extract @a code from
+ * @param[out] code where to write the extracted code
+ * @return #GNUNET_OK if a @a code was extracted
+ */
+static enum GNUNET_GenericReturnValue
+extract_code (const char *wire_subject,
+              uint64_t *code)
+{
+  unsigned long long c;
+  const char *pos;
+
+  if (0 !=
+      strcasestr (wire_subject,
+                  "anastasis"))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Keyword 'anastasis' missing in subject `%s', ignoring 
transfer\n",
+                wire_subject);
+    return GNUNET_SYSERR;
+  }
+  pos = wire_subject;
+  while ( ('\0' != *pos) &&
+          (! isdigit ((int) *pos)) )
+    pos++;
+  if (1 !=
+      sscanf (pos,
+              "%llu",
+              &c))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Did not find any code number in subject `%s', ignoring 
transfer\n",
+                wire_subject);
+    return GNUNET_SYSERR;
+  }
+
+  *code = (uint64_t) c;
+  return GNUNET_OK;
+}
diff --git a/src/authorization/iban.h b/src/authorization/iban.h
index c95c00d..70db7ea 100644
--- a/src/authorization/iban.h
+++ b/src/authorization/iban.h
@@ -32,7 +32,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
 struct IbanEventP
 {
   /**
-   * Header of type #TALER_DBEVENT_TYPE_ANASTASIS_AUTH_IBAN_TRANSFER.
+   * Header of type #TALER_DBEVENT_ANASTASIS_AUTH_IBAN_TRANSFER.
    */
   struct GNUNET_DB_EventHeaderP header;
 

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