gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: improvements in extension handli


From: gnunet
Subject: [taler-exchange] branch master updated: improvements in extension handling
Date: Sat, 22 Jan 2022 00:30:29 +0100

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

oec pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 1962ed6b improvements in extension handling
1962ed6b is described below

commit 1962ed6b0b44c6c7d3503b3340da1be147e25f87
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Sat Jan 22 00:26:43 2022 +0100

    improvements in extension handling
    
    - extensions_sig is needed globally
    - keep original json with config of extension
    - fixed various bugs re: extension handling
---
 src/exchange/taler-exchange-httpd.c                |   7 ++
 src/exchange/taler-exchange-httpd.h                |   5 +
 src/exchange/taler-exchange-httpd_extensions.c     | 138 +++++++++++----------
 src/exchange/taler-exchange-httpd_keys.c           |  92 ++++++++++----
 .../taler-exchange-httpd_management_extensions.c   |  12 +-
 src/exchangedb/plugin_exchangedb_postgres.c        |   5 +-
 src/include/taler_extensions.h                     |  14 +--
 7 files changed, 171 insertions(+), 102 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd.c 
b/src/exchange/taler-exchange-httpd.c
index 59398c6f..5fe70730 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -152,6 +152,13 @@ bool TEH_suicide;
  */
 struct TALER_Extension **TEH_extensions;
 
+/**
+ * Signature of the configuration of all enabled extensions,
+ * signed by the exchange's offline master key with purpose
+ * TALER_SIGNATURE_MASTER_EXTENSION.
+ */
+struct TALER_MasterSignatureP TEH_extensions_sig;
+
 /**
  * Value to return from main()
  */
diff --git a/src/exchange/taler-exchange-httpd.h 
b/src/exchange/taler-exchange-httpd.h
index 39666379..017d5520 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -206,6 +206,11 @@ extern struct GNUNET_CURL_Context *TEH_curl_ctx;
  */
 extern struct TALER_Extension **TEH_extensions;
 
+/*
+ * Signature of the offline master key of all enabled extensions' configuration
+ */
+extern struct TALER_MasterSignatureP TEH_extensions_sig;
+
 /* TODO: this will not work anymore, once we have plugable extensions */
 #define TEH_extension_enabled(ext) (0 <= ext && TALER_Extension_MaxPredefined 
> \
                                     ext && \
diff --git a/src/exchange/taler-exchange-httpd_extensions.c 
b/src/exchange/taler-exchange-httpd_extensions.c
index 1a2c4552..0245797d 100644
--- a/src/exchange/taler-exchange-httpd_extensions.c
+++ b/src/exchange/taler-exchange-httpd_extensions.c
@@ -27,29 +27,58 @@
 #include "taler_extensions.h"
 #include <jansson.h>
 
+/**
+ * @brief implements the TALER_Extension.disable interface.
+ */
+void
+age_restriction_disable (struct TALER_Extension *this)
+{
+  if (NULL == this)
+    return;
+
+  this->config = NULL;
+
+  if (NULL != this->config_json)
+  {
+    json_decref (this->config_json);
+    this->config_json = NULL;
+  }
+}
+
+
 /**
  * @brief implements the TALER_Extension.parse_and_set_config interface.
+ * @param this if NULL, only tests the configuration
+ * @param config the configuration as json
  */
 static enum GNUNET_GenericReturnValue
 age_restriction_parse_and_set_config (struct TALER_Extension *this,
-                                      const json_t *config)
+                                      json_t *config)
 {
-  enum GNUNET_GenericReturnValue ret;
   struct TALER_AgeMask mask = {0};
+  enum GNUNET_GenericReturnValue ret;
 
   ret = TALER_agemask_parse_json (config, &mask);
   if (GNUNET_OK != ret)
     return ret;
 
-  if (this != NULL && TALER_Extension_AgeRestriction == this->type)
-  {
-    if (NULL != this->config)
-    {
-      GNUNET_free (this->config);
-    }
-    this->config = GNUNET_malloc (sizeof(struct TALER_AgeMask));
-    GNUNET_memcpy (this->config, &mask, sizeof(struct TALER_AgeMask));
-  }
+  /* only testing the parser */
+  if (this == NULL)
+    return GNUNET_OK;
+
+  if (TALER_Extension_AgeRestriction != this->type)
+    return GNUNET_SYSERR;
+
+  if (NULL != this->config)
+    GNUNET_free (this->config);
+
+  this->config = GNUNET_malloc (sizeof(struct TALER_AgeMask));
+  GNUNET_memcpy (this->config, &mask, sizeof(struct TALER_AgeMask));
+
+  if (NULL != this->config_json)
+    json_decref (this->config_json);
+
+  this->config_json = config;
 
   return GNUNET_OK;
 }
@@ -61,28 +90,9 @@ age_restriction_parse_and_set_config (struct TALER_Extension 
*this,
 static enum GNUNET_GenericReturnValue
 age_restriction_test_config (const json_t *config)
 {
-  return age_restriction_parse_and_set_config (NULL, config);
-}
-
+  struct TALER_AgeMask mask = {0};
 
-/**
- * @brief implements the TALER_Extension.config_to_json interface.
- */
-static json_t *
-age_restriction_config_to_json (const struct TALER_Extension *this)
-{
-  const struct TALER_AgeMask *mask;
-  if (NULL == this || TALER_Extension_AgeRestriction != this->type)
-    return NULL;
-
-  mask = (struct TALER_AgeMask *) this->config;
-  json_t *config =  GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_string ("extension", this->name),
-    GNUNET_JSON_pack_string ("mask",
-                             TALER_age_mask_to_string (mask))
-    );
-
-  return config;
+  return TALER_agemask_parse_json (config, &mask);
 }
 
 
@@ -91,26 +101,17 @@ static struct TALER_Extension extension_age_restriction = {
   .type = TALER_Extension_AgeRestriction,
   .name = "age_restriction",
   .critical = false,
+  .version = "1",
   .config = NULL,   // disabled per default
+  .config_json = NULL,
+  .disable = &age_restriction_disable,
   .test_config = &age_restriction_test_config,
   .parse_and_set_config = &age_restriction_parse_and_set_config,
-  .config_to_json = &age_restriction_config_to_json,
-};
-
-/* TODO: The extension for peer2peer */
-static struct TALER_Extension extension_peer2peer = {
-  .type = TALER_Extension_Peer2Peer,
-  .name = "peer2peer",
-  .critical = false,
-  .config = NULL,   // disabled per default
-  .test_config = NULL, // TODO
-  .parse_and_set_config = NULL, // TODO
-  .config_to_json = NULL, // TODO
 };
 
-
 /**
- * Create a list with the extensions for Age Restriction and Peer2Peer
+ * Create a list with the extensions for Age Restriction (and later Peer2Peer,
+ * ...)
  */
 static struct TALER_Extension **
 get_known_extensions ()
@@ -120,7 +121,6 @@ get_known_extensions ()
     TALER_Extension_MaxPredefined + 1,
     struct TALER_Extension *);
   list[TALER_Extension_AgeRestriction] = &extension_age_restriction;
-  list[TALER_Extension_Peer2Peer] = &extension_peer2peer;
   list[TALER_Extension_MaxPredefined] = NULL;
 
   return list;
@@ -172,14 +172,13 @@ extension_update_event_cb (void *cls,
 
   // Get the config from the database as string
   {
-    char *config_str;
+    char *config_str = NULL;
     enum GNUNET_DB_QueryStatus qs;
     struct TALER_Extension *extension;
     json_error_t err;
     json_t *config;
     enum GNUNET_GenericReturnValue ret;
 
-    // TODO: make this a safe lookup
     extension  = TEH_extensions[type];
 
     qs = TEH_plugin->get_extension_config (TEH_plugin->cls,
@@ -194,6 +193,13 @@ extension_update_event_cb (void *cls,
       return;
     }
 
+    // No config found -> extension is disabled
+    if (NULL == config_str)
+    {
+      extension->disable (extension);
+      return;
+    }
+
     // Parse the string as JSON
     config = json_loads (config_str, JSON_DECODE_ANY, &err);
     if (NULL == config)
@@ -223,25 +229,29 @@ extension_update_event_cb (void *cls,
 enum GNUNET_GenericReturnValue
 TEH_extensions_init ()
 {
+  /* Populate the known extensions. */
   TEH_extensions = get_known_extensions ();
 
+  /* Set the event handler for updates */
+  struct GNUNET_DB_EventHeaderP ev = {
+    .size = htons (sizeof (ev)),
+    .type = htons (TALER_DBEVENT_EXCHANGE_EXTENSIONS_UPDATED),
+  };
+  extensions_eh = TEH_plugin->event_listen (TEH_plugin->cls,
+                                            GNUNET_TIME_UNIT_FOREVER_REL,
+                                            &ev,
+                                            &extension_update_event_cb,
+                                            NULL);
+  if (NULL == extensions_eh)
   {
-    struct GNUNET_DB_EventHeaderP ev = {
-      .size = htons (sizeof (ev)),
-      .type = htons (TALER_DBEVENT_EXCHANGE_EXTENSIONS_UPDATED),
-    };
-
-    extensions_eh = TEH_plugin->event_listen (TEH_plugin->cls,
-                                              GNUNET_TIME_UNIT_FOREVER_REL,
-                                              &ev,
-                                              &extension_update_event_cb,
-                                              NULL);
-    if (NULL == extensions_eh)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
   }
+
+  /* Trigger the initial load of configuration from the db */
+  for (struct TALER_Extension **it = TEH_extensions; NULL != *it; it++)
+    extension_update_event_cb (NULL, &(*it)->type, sizeof((*it)->type));
+
   return GNUNET_OK;
 }
 
diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index 30bbe8eb..7c64cdb7 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -1703,29 +1703,79 @@ create_krd (struct TEH_KeyStateHandle *ksh,
           &TEH_kyc_config.wallet_balance_limit)));
   }
 
-  // Signal support for the age-restriction extension, if so configured, and
-  // add the array of age-restricted denominations.
-  if (TEH_extension_enabled (TALER_Extension_AgeRestriction) &&
-      NULL != age_restricted_denoms)
+  // Signal support for the configured, enabled extensions.
   {
-    struct TALER_AgeMask *mask;
-    json_t *config;
-
-    mask = (struct
-            TALER_AgeMask *) TEH_extensions[TALER_Extension_AgeRestriction]->
-           config;
-    config = GNUNET_JSON_PACK (
-      GNUNET_JSON_pack_bool ("critical", false),
-      GNUNET_JSON_pack_string ("version", "1"),
-      GNUNET_JSON_pack_string ("age_groups", TALER_age_mask_to_string (mask)));
-    GNUNET_assert (NULL != config);
-    GNUNET_assert (
-      0 ==
-      json_object_set_new (
+    json_t *extensions = json_object ();
+    bool has_extensions;
+
+    /* Fill in the configurations of the enabled extensions */
+    for (struct TALER_Extension **it = TEH_extensions;
+         NULL != *it;
+         it++)
+    {
+      const struct TALER_Extension *extension = *it;
+      json_t *ext;
+      json_t *config_json;
+      int r;
+
+      /* skip if not configured == disabled */
+      if (NULL == extension->config)
+        continue;
+
+      has_extensions = true;
+
+      GNUNET_assert (NULL != extension->config_json);
+
+      config_json = json_copy (extension->config_json);
+      GNUNET_assert (NULL != config_json);
+
+      ext = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_bool ("critical",
+                               extension->critical),
+        GNUNET_JSON_pack_string ("version",
+                                 extension->version),
+        GNUNET_JSON_pack_object_steal ("config",
+                                       config_json)
+        );
+      GNUNET_assert (NULL != ext);
+
+      r = json_object_set_new (
+        extensions,
+        extension->name,
+        ext);
+
+      GNUNET_assert (0 == r);
+    }
+
+    /* Update the keys object with the extensions */
+    if (has_extensions)
+    {
+      json_t *sig;
+      int r;
+
+      r = json_object_set_new (
         keys,
-        "age_restriction",
-        config));
+        "extensions",
+        extensions);
+      GNUNET_assert (0 == r);
+
+      /* add extensions_sig */
+      sig = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_data_auto ("extensions_sig",
+                                    &TEH_extensions_sig));
+
+      /* update the keys object with extensions_sig */
+      r = json_object_update (keys, sig);
+      GNUNET_assert (0 == r);
+    }
+  }
 
+
+  // Special case for age restrictions: if enabled, provide the lits of
+  // age-restricted denominations.
+  if (TEH_extension_enabled (TALER_Extension_AgeRestriction) &&
+      NULL != age_restricted_denoms)
+  {
     GNUNET_assert (
       0 ==
       json_object_set_new (
@@ -1734,8 +1784,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
         age_restricted_denoms));
   }
 
-  // TODO: signal support and configuration for the P2P extension, once
-  // implemented.
 
   {
     char *keys_json;
diff --git a/src/exchange/taler-exchange-httpd_management_extensions.c 
b/src/exchange/taler-exchange-httpd_management_extensions.c
index 8476e669..17db8e8c 100644
--- a/src/exchange/taler-exchange-httpd_management_extensions.c
+++ b/src/exchange/taler-exchange-httpd_management_extensions.c
@@ -49,6 +49,7 @@ struct SetExtensionsContext
 {
   uint32_t num_extensions;
   struct Extension *extensions;
+  struct TALER_MasterSignatureP extensions_sig;
 };
 
 /**
@@ -132,6 +133,9 @@ set_extensions (void *cls,
 
   }
 
+  /* All extensions configured, update the signature */
+  TEH_extensions_sig = sec->extensions_sig;
+
   return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; /* only 'success', so >=0, 
matters here */
 }
 
@@ -143,15 +147,14 @@ TEH_handler_management_post_extensions (
 {
   MHD_RESULT ret;
   json_t *extensions;
-  struct TALER_MasterSignatureP sig = {0};
+  struct SetExtensionsContext sec = {0};
   struct GNUNET_JSON_Specification top_spec[] = {
     GNUNET_JSON_spec_json ("extensions",
                            &extensions),
     GNUNET_JSON_spec_fixed_auto ("extensions_sig",
-                                 &sig),
+                                 &sec.extensions_sig),
     GNUNET_JSON_spec_end ()
   };
-  struct SetExtensionsContext sec = {0};
 
   /* Parse the top level json structure */
   {
@@ -193,7 +196,7 @@ TEH_handler_management_post_extensions (
     if (GNUNET_OK != TALER_exchange_offline_extension_config_hash_verify (
           &h_config,
           &TEH_master_public_key,
-          &sig))
+          &sec.extensions_sig))
     {
       GNUNET_JSON_parse_free (top_spec);
       return TALER_MHD_reply_with_error (
@@ -248,7 +251,6 @@ TEH_handler_management_post_extensions (
           TALER_EC_GENERIC_PARAMETER_MALFORMED,
           "invalid configuration for extension");
         goto CLEANUP;
-
       }
 
       /* We have a validly signed JSON object for the extension.  Increment its
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 918fc38c..f9f0ce41 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -11455,6 +11455,7 @@ postgres_get_extension_config (void *cls,
     GNUNET_PQ_query_param_end
   };
   bool is_null;
+  *config = NULL;
   struct GNUNET_PQ_ResultSpec rs[] = {
     GNUNET_PQ_result_spec_allow_null (
       GNUNET_PQ_result_spec_string ("config", config),
@@ -11467,10 +11468,6 @@ postgres_get_extension_config (void *cls,
                                                  "get_extension_config",
                                                  params,
                                                  rs);
-  if (is_null)
-  {
-    *config = NULL;
-  }
   return qs;
 }
 
diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h
index 31e5c673..7199304d 100644
--- a/src/include/taler_extensions.h
+++ b/src/include/taler_extensions.h
@@ -31,26 +31,27 @@
 enum TALER_Extension_Type
 {
   TALER_Extension_AgeRestriction = 0,
-  TALER_Extension_Peer2Peer = 1,
-  TALER_Extension_MaxPredefined = 2 // Must be last
+  TALER_Extension_MaxPredefined = 1 // Must be last of the predefined
 };
 
 /*
  * Represents the implementation of an extension.
+ * TODO: add documentation
  */
 struct TALER_Extension
 {
   enum TALER_Extension_Type type;
   char *name;
   bool critical;
-  bool enabled;
+  char *version;
   void *config;
+  json_t *config_json;
 
+  void (*disable)(struct TALER_Extension *this);
   enum GNUNET_GenericReturnValue (*test_config)(const json_t *config);
   enum GNUNET_GenericReturnValue (*parse_and_set_config)(struct
                                                          TALER_Extension *this,
-                                                         const json_t *config);
-  json_t *(*config_to_json)(const struct TALER_Extension *this);
+                                                         json_t *config);
 };
 
 /**
@@ -132,8 +133,7 @@ TALER_get_age_mask (const struct 
GNUNET_CONFIGURATION_Handle *cfg,
 
 
 /*
- * TALER Peer2Peer Extension
- * TODO oec
+ * TODO: Add Peer2Peer Extension
  */
 
 #endif

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