improvements in extension handling
- extensions_sig is needed globally - keep original json with config of extension - fixed various bugs re: extension handling
This commit is contained in:
parent
0b56de6c99
commit
1962ed6b0b
@ -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()
|
||||
*/
|
||||
|
@ -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 && \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
// Signal support for the configured, enabled extensions.
|
||||
{
|
||||
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,
|
||||
"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)
|
||||
{
|
||||
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 (
|
||||
keys,
|
||||
"age_restriction",
|
||||
config));
|
||||
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user