diff options
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/Makefile.am | 1 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd.c | 5 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd.h | 10 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_extensions.c | 131 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 49 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_management_extensions.c | 38 |
6 files changed, 60 insertions, 174 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index e7688f735..44487a3a7 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -119,6 +119,7 @@ taler_exchange_httpd_LDADD = \ $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/exchangedb/libtalerexchangedb.la \ $(top_builddir)/src/util/libtalerutil.la \ + $(top_builddir)/src/extensions/libtalerextensions.la \ -lmicrohttpd \ -lgnunetcurl \ -lgnunetutil \ diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 5fe707304..ae5847d11 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -148,11 +148,6 @@ int TEH_check_invariants_flag; bool TEH_suicide; /** - * Global register of extensions - */ -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. diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 017d5520b..d3b1ba84a 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -201,21 +201,11 @@ extern volatile bool MHD_terminating; */ extern struct GNUNET_CURL_Context *TEH_curl_ctx; -/** - * The manifest of the available extensions, NULL terminated - */ -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 && \ - NULL != TEH_extensions[ext]->config) - /** * @brief Struct describing an URL and the handler for it. */ diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c index 0245797d4..8edb24d40 100644 --- a/src/exchange/taler-exchange-httpd_extensions.c +++ b/src/exchange/taler-exchange-httpd_extensions.c @@ -28,106 +28,6 @@ #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, - json_t *config) -{ - struct TALER_AgeMask mask = {0}; - enum GNUNET_GenericReturnValue ret; - - ret = TALER_agemask_parse_json (config, &mask); - if (GNUNET_OK != ret) - return ret; - - /* 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; -} - - -/** - * @brief implements the TALER_Extension.test_config interface. - */ -static enum GNUNET_GenericReturnValue -age_restriction_test_config (const json_t *config) -{ - struct TALER_AgeMask mask = {0}; - - return TALER_agemask_parse_json (config, &mask); -} - - -/* The extension for age restriction */ -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, -}; - -/** - * Create a list with the extensions for Age Restriction (and later Peer2Peer, - * ...) - */ -static struct TALER_Extension ** -get_known_extensions () -{ - - struct TALER_Extension **list = GNUNET_new_array ( - TALER_Extension_MaxPredefined + 1, - struct TALER_Extension *); - list[TALER_Extension_AgeRestriction] = &extension_age_restriction; - list[TALER_Extension_MaxPredefined] = NULL; - - return list; -} - - -/** * Handler listening for extensions updates by other exchange * services. */ @@ -148,6 +48,7 @@ extension_update_event_cb (void *cls, { (void) cls; enum TALER_Extension_Type type; + const struct TALER_Extension *extension; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received extensions update event\n"); @@ -161,12 +62,15 @@ extension_update_event_cb (void *cls, } type = *(enum TALER_Extension_Type *) extra; - /* TODO: This check will not work once we have plugable extensions */ - if (type <0 || type >= TALER_Extension_MaxPredefined) + + + /* Get the corresponding extension */ + extension = TALER_extensions_get_by_type (type); + if (NULL == extension) { GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Oops, incorrect type for TALER_Extension_type\n"); + "Oops, unknown extension type: %d\n", type); return; } @@ -174,13 +78,10 @@ extension_update_event_cb (void *cls, { char *config_str = NULL; enum GNUNET_DB_QueryStatus qs; - struct TALER_Extension *extension; json_error_t err; json_t *config; enum GNUNET_GenericReturnValue ret; - extension = TEH_extensions[type]; - qs = TEH_plugin->get_extension_config (TEH_plugin->cls, extension->name, &config_str); @@ -193,10 +94,10 @@ extension_update_event_cb (void *cls, return; } - // No config found -> extension is disabled + // No config found -> disable extension if (NULL == config_str) { - extension->disable (extension); + extension->disable ((struct TALER_Extension *) extension); return; } @@ -214,7 +115,10 @@ extension_update_event_cb (void *cls, } // Call the parser for the extension - ret = extension->parse_and_set_config (extension, config); + ret = extension->load_json_config ( + (struct TALER_Extension *) extension, + config); + if (GNUNET_OK != ret) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -229,8 +133,7 @@ extension_update_event_cb (void *cls, enum GNUNET_GenericReturnValue TEH_extensions_init () { - /* Populate the known extensions. */ - TEH_extensions = get_known_extensions (); + TALER_extensions_init (); /* Set the event handler for updates */ struct GNUNET_DB_EventHeaderP ev = { @@ -249,8 +152,10 @@ TEH_extensions_init () } /* 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)); + for (const struct TALER_Extension *it = TALER_extensions_get_head (); + NULL != it->next; + it = it->next) + 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 7c64cdb75..de9b81cdd 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -744,14 +744,14 @@ load_age_mask (const char*section_name) { static const struct TALER_AgeMask null_mask = {0}; struct TALER_AgeMask age_mask = {0}; + /* TODO: optimize by putting this into global? */ const struct TALER_Extension *age_ext = - TEH_extensions[TALER_Extension_AgeRestriction]; + TALER_extensions_get_by_type (TALER_Extension_AgeRestriction); // Get the age mask from the extension, if configured - if (NULL != age_ext->config) - { + /* TODO: optimize by putting this into global? */ + if (TALER_extensions_is_enabled (age_ext)) age_mask = *(struct TALER_AgeMask *) age_ext->config; - } if (age_mask.mask == 0) { @@ -1706,14 +1706,14 @@ create_krd (struct TEH_KeyStateHandle *ksh, // Signal support for the configured, enabled extensions. { json_t *extensions = json_object (); - bool has_extensions; + bool has_extensions = false; + bool age_restriction_enabled = false; /* Fill in the configurations of the enabled extensions */ - for (struct TALER_Extension **it = TEH_extensions; - NULL != *it; - it++) + for (const struct TALER_Extension *extension = TALER_extensions_get_head (); + NULL != extension; + extension = extension->next) { - const struct TALER_Extension *extension = *it; json_t *ext; json_t *config_json; int r; @@ -1722,7 +1722,10 @@ create_krd (struct TEH_KeyStateHandle *ksh, if (NULL == extension->config) continue; + /* flag our findings so far */ has_extensions = true; + age_restriction_enabled = (extension->type == + TALER_Extension_AgeRestriction); GNUNET_assert (NULL != extension->config_json); @@ -1743,7 +1746,6 @@ create_krd (struct TEH_KeyStateHandle *ksh, extensions, extension->name, ext); - GNUNET_assert (0 == r); } @@ -1768,20 +1770,20 @@ create_krd (struct TEH_KeyStateHandle *ksh, 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 (age_restriction_enabled && + NULL != age_restricted_denoms) + { + GNUNET_assert ( + 0 == + json_object_set_new ( + keys, + "age_restricted_denoms", + age_restricted_denoms)); + } - // 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 ( - keys, - "age_restricted_denoms", - age_restricted_denoms)); } @@ -1884,7 +1886,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) GNUNET_assert (NULL != denoms); // If age restriction is enabled, initialize the array of age restricted denoms. - if (TEH_extension_enabled (TALER_Extension_AgeRestriction)) + /* TODO: optimize by putting this into global? */ + if (TALER_extensions_is_enabled_type (TALER_Extension_AgeRestriction)) { age_restricted_denoms = json_array (); GNUNET_assert (NULL != age_restricted_denoms); diff --git a/src/exchange/taler-exchange-httpd_management_extensions.c b/src/exchange/taler-exchange-httpd_management_extensions.c index 17db8e8c4..17b000067 100644 --- a/src/exchange/taler-exchange-httpd_management_extensions.c +++ b/src/exchange/taler-exchange-httpd_management_extensions.c @@ -79,14 +79,14 @@ set_extensions (void *cls, for (uint32_t i = 0; i<sec->num_extensions; i++) { struct Extension *ext = &sec->extensions[i]; + const struct TALER_Extension *taler_ext; enum GNUNET_DB_QueryStatus qs; char *config; - /* Sanity check. - * TODO: This will not work anymore, once we have plugable extensions - */ - if (0 > ext->type || TALER_Extension_MaxPredefined <= ext->type) + taler_ext = TALER_extensions_get_by_type (ext->type); + if (NULL == taler_ext) { + /* No such extension found */ GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; } @@ -104,7 +104,7 @@ set_extensions (void *cls, qs = TEH_plugin->set_extension_config ( TEH_plugin->cls, - TEH_extensions[ext->type]->name, + taler_ext->name, config); if (qs < 0) @@ -183,17 +183,11 @@ TEH_handler_management_post_extensions ( /* Verify the signature */ { struct TALER_ExtensionConfigHash h_config; - if (GNUNET_OK != TALER_extension_config_hash (extensions, &h_config)) - { - GNUNET_JSON_parse_free (top_spec); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "invalid object, non-hashable"); - } - if (GNUNET_OK != TALER_exchange_offline_extension_config_hash_verify ( + if (GNUNET_OK != + TALER_JSON_extensions_config_hash (extensions, &h_config) || + GNUNET_OK != + TALER_exchange_offline_extension_config_hash_verify ( &h_config, &TEH_master_public_key, &sec.extensions_sig)) @@ -207,7 +201,6 @@ TEH_handler_management_post_extensions ( } } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received /management/extensions\n"); @@ -217,7 +210,7 @@ TEH_handler_management_post_extensions ( /* Now parse individual extensions and signatures from those objects. */ { - const struct TALER_Extension *extension; + const struct TALER_Extension *extension = NULL; const char *name; json_t *config; int idx = 0; @@ -225,11 +218,8 @@ TEH_handler_management_post_extensions ( json_object_foreach (extensions, name, config){ /* 1. Make sure name refers to a supported extension */ - if (GNUNET_OK != TALER_extension_get_by_name (name, - (const struct - TALER_Extension **) - TEH_extensions, - &extension)) + extension = TALER_extensions_get_by_name (name); + if (NULL == extension) { ret = TALER_MHD_reply_with_error ( connection, @@ -243,7 +233,9 @@ TEH_handler_management_post_extensions ( sec.extensions[idx].type = extension->type; /* 2. Make sure the config is sound */ - if (GNUNET_OK != extension->test_config (sec.extensions[idx].config)) + if (GNUNET_OK != + extension->test_json_config ( + sec.extensions[idx].config)) { ret = TALER_MHD_reply_with_error ( connection, |