refactor extensions: config -> manifest

This commit is contained in:
Özgür Kesim 2022-10-05 16:07:09 +02:00
parent 477d009cb0
commit 2524dfc8d3
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
32 changed files with 34588 additions and 396 deletions

View File

@ -533,7 +533,7 @@ AC_CONFIG_FILES([Makefile
src/exchange-tools/Makefile
src/extensions/Makefile
src/extensions/age_restriction/Makefile
src/extensions/policy_auction/Makefile
src/extensions/policy_brandt_vickrey_auction/Makefile
src/lib/Makefile
src/kyclogic/Makefile
src/testing/Makefile

View File

@ -32,7 +32,7 @@ SUBDIRS = \
auditor \
lib \
exchange-tools \
extensions/policy_auction \
extensions/age_restriction \
extensions/policy_brandt_vickrey_auction \
testing \
benchmark

View File

@ -140,6 +140,7 @@ static const struct GNUNET_CONFIGURATION_Handle *kcfg;
/**
* Age restriction configuration
*/
static bool ar_enabled = false;
static struct TALER_AgeRestrictionConfig ar_config = {0};
/**
@ -2169,14 +2170,14 @@ upload_extensions (const char *exchange_url,
/* 2. Verify the signature */
{
struct TALER_ExtensionConfigHashP h_config;
struct TALER_ExtensionManifestsHashP h_manifests;
if (GNUNET_OK !=
TALER_JSON_extensions_config_hash (extensions, &h_config))
TALER_JSON_extensions_manifests_hash (extensions, &h_manifests))
{
GNUNET_JSON_parse_free (spec);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"couldn't hash extensions\n");
"couldn't hash extensions' manifests\n");
global_ret = EXIT_FAILURE;
test_shutdown ();
return;
@ -2186,8 +2187,8 @@ upload_extensions (const char *exchange_url,
load_offline_key (GNUNET_NO))
return;
if (GNUNET_OK != TALER_exchange_offline_extension_config_hash_verify (
&h_config,
if (GNUNET_OK != TALER_exchange_offline_extension_manifests_hash_verify (
&h_manifests,
&master_pub,
&sig))
{
@ -3889,7 +3890,7 @@ load_age_mask (const char*section_name)
static const struct TALER_AgeMask null_mask = {0};
enum GNUNET_GenericReturnValue ret;
if (! ar_config.enabled)
if (! ar_enabled)
return null_mask;
if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value (
@ -4263,7 +4264,7 @@ do_extensions_show (char *const *args)
ret = json_object_set_new (exts,
extension->name,
extension->config_to_json (extension));
extension->manifest (extension));
GNUNET_assert (-1 != ret);
}
@ -4286,7 +4287,7 @@ static void
do_extensions_sign (char *const *args)
{
json_t *extensions = json_object ();
struct TALER_ExtensionConfigHashP h_config;
struct TALER_ExtensionManifestsHashP h_manifests;
struct TALER_MasterSignatureP sig;
const struct TALER_Extensions *it;
bool found = false;
@ -4294,7 +4295,7 @@ do_extensions_sign (char *const *args)
GNUNET_assert (NULL != extensions);
for (it = TALER_extensions_get_head ();
NULL != it;
NULL != it && NULL != it->extension;
it = it->next)
{
const struct TALER_Extension *ext = it->extension;
@ -4305,16 +4306,15 @@ do_extensions_sign (char *const *args)
GNUNET_assert (0 ==
json_object_set_new (extensions,
ext->name,
ext->config_to_json (
ext)));
ext->manifest (ext)));
}
if (! found)
return;
if (GNUNET_OK !=
TALER_JSON_extensions_config_hash (extensions,
&h_config))
TALER_JSON_extensions_manifests_hash (extensions,
&h_manifests))
{
json_decref (extensions);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@ -4329,7 +4329,7 @@ do_extensions_sign (char *const *args)
return;
}
TALER_exchange_offline_extension_config_hash_sign (&h_config,
TALER_exchange_offline_extension_manifests_hash_sign (&h_manifests,
&master_priv,
&sig);
obj = GNUNET_JSON_PACK (
@ -4339,6 +4339,10 @@ do_extensions_sign (char *const *args)
"extensions_sig",
&sig));
GNUNET_log(GNUNET_ERROR_TYPE_INFO,
"DEBUG sending extensions object: '%s'\n",
json_dumps(obj, JSON_INDENT(2)));
output_operation (OP_EXTENSIONS,
obj);
next (args);
@ -4547,7 +4551,7 @@ run (void *cls,
/* load extensions */
GNUNET_assert (GNUNET_OK ==
TALER_extensions_load (kcfg));
TALER_extensions_init (kcfg));
/* setup age restriction, if applicable */
{
@ -4557,7 +4561,7 @@ run (void *cls,
(arc = TALER_extensions_get_age_restriction_config ()))
{
ar_config = *arc;
ar_config.enabled = true;
ar_enabled = true;
}
}

View File

@ -102,6 +102,7 @@ const struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
*
* Set after loading the library, enabled in database event handler.
*/
bool TEH_age_restriction_enabled = false;
struct TALER_AgeRestrictionConfig TEH_age_restriction_config = {0};
/**

View File

@ -363,6 +363,7 @@ struct TEH_RequestHandler
/* Age restriction configuration */
extern bool TEH_age_restriction_enabled;
extern struct TALER_AgeRestrictionConfig TEH_age_restriction_config;
#endif

View File

@ -242,7 +242,7 @@ batch_deposit_transaction (void *cls,
MHD_RESULT *mhd_ret)
{
struct BatchDepositContext *dc = cls;
enum GNUNET_DB_QueryStatus qs;
enum GNUNET_DB_QueryStatus qs = GNUNET_OK;
bool balance_ok;
bool in_conflict;

View File

@ -77,67 +77,66 @@ extension_update_event_cb (void *cls,
return;
}
// Get the config from the database as string
if (extension->has_config)
// Get the manifest from the database as string
{
char *config_str = NULL;
char *manifest_str = NULL;
enum GNUNET_DB_QueryStatus qs;
json_error_t err;
json_t *config;
json_t *manifest_js;
enum GNUNET_GenericReturnValue ret;
qs = TEH_plugin->get_extension_config (TEH_plugin->cls,
qs = TEH_plugin->get_extension_manifest (TEH_plugin->cls,
extension->name,
&config_str);
&manifest_str);
if (qs < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Couldn't get extension config\n");
"Couldn't get extension manifest\n");
GNUNET_break (0);
return;
}
// No config found -> disable extension
if (NULL == config_str)
if (NULL == manifest_str)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"No configuration found for extension %s, disabling it\n",
"No manifest found for extension %s, disabling it\n",
extension->name);
extension->disable ((struct TALER_Extension *) extension);
return;
}
// Parse the string as JSON
config = json_loads (config_str, JSON_DECODE_ANY, &err);
if (NULL == config)
manifest_js = json_loads (manifest_str, JSON_DECODE_ANY, &err);
if (NULL == manifest_js)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to parse config for extension `%s' as JSON: %s (%s)\n",
"Failed to parse manifest for extension `%s' as JSON: %s (%s)\n",
extension->name,
err.text,
err.source);
GNUNET_break (0);
free (config_str);
free (manifest_js);
return;
}
// Call the parser for the extension
ret = extension->load_json_config (
ret = extension->load_config (
(struct TALER_Extension *) extension,
json_object_get (config, "config"));
json_object_get (manifest_js, "config"));
if (GNUNET_OK != ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Couldn't parse configuration for extension %s from the database: %s\n",
"Couldn't parse configuration for extension %s from the manifest in the database: %s\n",
extension->name,
config_str);
manifest_str);
GNUNET_break (0);
}
free (config_str);
json_decref (config);
free (manifest_str);
json_decref (manifest_js);
}
/* Special case age restriction: Update global flag and mask */
@ -145,11 +144,15 @@ extension_update_event_cb (void *cls,
{
const struct TALER_AgeRestrictionConfig *conf =
TALER_extensions_get_age_restriction_config ();
TEH_age_restriction_enabled = false;
if (NULL != conf)
{
TEH_age_restriction_enabled = true;
TEH_age_restriction_config = *conf;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"[age restriction] DB event has changed the config to %s with mask: %s\n",
conf->enabled ? "enabled": "disabled",
TEH_age_restriction_enabled ? "enabled": "DISABLED",
TALER_age_mask_to_string (&conf->mask));
}
@ -167,13 +170,22 @@ TEH_extensions_init ()
/* Load the shared libraries first */
if (GNUNET_OK !=
TALER_extensions_load (TEH_cfg))
TALER_extensions_init (TEH_cfg))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"failed to load extensions");
return GNUNET_SYSERR;
}
/* Check for age restriction */
{
const struct TALER_AgeRestrictionConfig *arc;
if (NULL !=
(arc = TALER_extensions_get_age_restriction_config ()))
TEH_age_restriction_config = *arc;
}
extensions_eh = TEH_plugin->event_listen (TEH_plugin->cls,
GNUNET_TIME_UNIT_FOREVER_REL,
&ev,
@ -192,16 +204,16 @@ TEH_extensions_init ()
{
const struct TALER_Extension *ext = it->extension;
uint32_t typ = htonl (ext->type);
char *conf = json_dumps (ext->config_to_json (ext), JSON_COMPACT);
char *manifest = json_dumps (ext->manifest (ext), JSON_COMPACT);
TEH_plugin->set_extension_config (TEH_plugin->cls,
TEH_plugin->set_extension_manifest (TEH_plugin->cls,
ext->name,
conf);
manifest);
extension_update_event_cb (NULL,
&typ,
sizeof(typ));
free (conf);
free (manifest);
}
return GNUNET_OK;

View File

@ -837,7 +837,7 @@ load_age_mask (const char*section_name)
if (GNUNET_OK == ret)
{
if (! TEH_age_restriction_config.enabled)
if (! TEH_age_restriction_enabled)
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"age restriction set in section %s, yet, age restriction is not enabled\n",
section_name);
@ -1907,7 +1907,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
iter = iter->next)
{
const struct TALER_Extension *extension = iter->extension;
json_t *ext;
json_t *manifest;
int r;
/* skip if not enabled */
@ -1917,26 +1917,14 @@ create_krd (struct TEH_KeyStateHandle *ksh,
/* flag our findings so far */
has_extensions = true;
ext = GNUNET_JSON_PACK (
GNUNET_JSON_pack_bool ("critical",
extension->critical),
GNUNET_JSON_pack_string ("version",
extension->version)
);
GNUNET_assert (NULL != ext);
if (extension->has_config)
{
GNUNET_assert (extension->config_json);
json_object_set_new (ext,
"config",
extension->config_json);
}
manifest = extension->manifest(extension);
GNUNET_assert(manifest);
r = json_object_set_new (
extensions,
extension->name,
ext);
manifest);
GNUNET_assert (0 == r);
}

View File

@ -80,7 +80,7 @@ set_extensions (void *cls,
struct Extension *ext = &sec->extensions[i];
const struct TALER_Extension *taler_ext;
enum GNUNET_DB_QueryStatus qs;
char *config;
char *manifest;
taler_ext = TALER_extensions_get_by_type (ext->type);
if (NULL == taler_ext)
@ -90,10 +90,8 @@ set_extensions (void *cls,
return GNUNET_DB_STATUS_HARD_ERROR;
}
GNUNET_assert (NULL != ext->config);
config = json_dumps (ext->config, JSON_COMPACT | JSON_SORT_KEYS);
if (NULL == config)
manifest = json_dumps (ext->config, JSON_COMPACT | JSON_SORT_KEYS);
if (NULL == manifest)
{
GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection,
@ -103,12 +101,12 @@ set_extensions (void *cls,
return GNUNET_DB_STATUS_HARD_ERROR;
}
qs = TEH_plugin->set_extension_config (
qs = TEH_plugin->set_extension_manifest (
TEH_plugin->cls,
taler_ext->name,
config);
manifest);
free (config);
free (manifest);
if (qs < 0)
{
@ -153,7 +151,7 @@ verify_extensions_from_json (
const char*name;
const struct TALER_Extension *extension;
size_t i = 0;
json_t *blob;
json_t *manifest;
GNUNET_assert (NULL != extensions);
GNUNET_assert (json_is_object (extensions));
@ -162,7 +160,7 @@ verify_extensions_from_json (
sec->extensions = GNUNET_new_array (sec->num_extensions,
struct Extension);
json_object_foreach (extensions, name, blob)
json_object_foreach (extensions, name, manifest)
{
int critical = 0;
json_t *config;
@ -178,14 +176,14 @@ verify_extensions_from_json (
}
if (GNUNET_OK !=
TALER_extensions_is_json_config (
blob, &critical, &version, &config))
TALER_extensions_parse_manifest (
manifest, &critical, &version, &config))
return GNUNET_SYSERR;
if (critical != extension->critical
|| 0 != strcmp (version, extension->version) // FIXME-oec: libtool compare
|| NULL == config
|| GNUNET_OK != extension->test_json_config (config))
|| GNUNET_OK != extension->load_config (NULL, config))
return GNUNET_SYSERR;
sec->extensions[i].type = extension->type;
@ -226,7 +224,8 @@ TEH_handler_management_post_extensions (
}
/* Ensure we have an object */
if (! json_is_object (extensions))
if ((! json_is_object (extensions)) &&
(! json_is_null (extensions)))
{
GNUNET_JSON_parse_free (top_spec);
return TALER_MHD_reply_with_error (
@ -238,13 +237,13 @@ TEH_handler_management_post_extensions (
/* Verify the signature */
{
struct TALER_ExtensionConfigHashP h_config;
struct TALER_ExtensionManifestsHashP h_manifests;
if (GNUNET_OK !=
TALER_JSON_extensions_config_hash (extensions, &h_config) ||
TALER_JSON_extensions_manifests_hash (extensions, &h_manifests) ||
GNUNET_OK !=
TALER_exchange_offline_extension_config_hash_verify (
&h_config,
TALER_exchange_offline_extension_manifests_hash_verify (
&h_manifests,
&TEH_master_public_key,
&sec.extensions_sig))
{

View File

@ -603,7 +603,7 @@ resolve_refreshes_reveal_denominations (
&rrc->coin_envelope_hash);
}
if (TEH_age_restriction_config.enabled &&
if (TEH_age_restriction_enabled &&
((NULL == old_age_commitment_json) !=
TALER_AgeCommitmentHash_isNullOrZero (
&rctx->melt.session.coin.h_age_commitment)))
@ -614,7 +614,7 @@ resolve_refreshes_reveal_denominations (
/* Reconstruct the old age commitment and verify its hash matches the one
* from the melt request */
if (TEH_age_restriction_config.enabled &&
if (TEH_age_restriction_enabled &&
(NULL != old_age_commitment_json))
{
enum GNUNET_GenericReturnValue res;

View File

@ -3922,7 +3922,7 @@ prepare_statements (struct PostgresClosure *pg)
"INSERT INTO extensions"
"(extension_id"
",name"
",config"
",manifest"
") VALUES "
"($1, $2, $3);",
3),
@ -4206,18 +4206,18 @@ prepare_statements (struct PostgresClosure *pg)
" AND start_row=$2"
" AND end_row=$3",
3),
/* Used in #postgres_set_extension_config */
/* Used in #postgres_set_extension_manifest */
GNUNET_PQ_make_prepare (
"set_extension_config",
"INSERT INTO extensions (name, config) VALUES ($1, $2) "
"set_extension_manifest",
"INSERT INTO extensions (name, manifest) VALUES ($1, $2) "
"ON CONFLICT (name) "
"DO UPDATE SET config=$2",
"DO UPDATE SET manifest=$2",
2),
/* Used in #postgres_get_extension_config */
/* Used in #postgres_get_extension_manifest */
GNUNET_PQ_make_prepare (
"get_extension_config",
"get_extension_manifest",
"SELECT "
" config "
" manifest "
"FROM extensions"
" WHERE name=$1;",
1),
@ -15199,25 +15199,25 @@ postgres_delete_shard_locks (void *cls)
/**
* Function called to save the configuration of an extension
* (age-restriction, peer2peer, ...). After successful storage of the
* configuration it triggers the corresponding event.
* Function called to save the manifest of an extension
* (age_restriction, poliy_merchant_refund, ...). After successful storage of
* the manifest it triggers the corresponding event.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param extension_name the name of the extension
* @param config JSON object of the configuration as string
* @param manifest JSON object of the manifest as string
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
postgres_set_extension_config (void *cls,
postgres_set_extension_manifest (void *cls,
const char *extension_name,
const char *config)
const char *manifest)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam pcfg =
(NULL == config || 0 == *config)
(NULL == manifest || 0 == *manifest)
? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_string (config);
: GNUNET_PQ_query_param_string (manifest);
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_string (extension_name),
pcfg,
@ -15225,24 +15225,24 @@ postgres_set_extension_config (void *cls,
};
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"set_extension_config",
"set_extension_manifest",
params);
}
/**
* Function called to get the configuration of an extension
* (age-restriction, peer2peer, ...)
* Function called to get the manifest of an extension
* (age_restriction, policy_merchant_refund, ...)
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param extension_name the name of the extension
* @param[out] config JSON object of the configuration as string
* @param[out] manifest Manifest of the extension encoded as JSON object
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
postgres_get_extension_config (void *cls,
postgres_get_extension_manifest (void *cls,
const char *extension_name,
char **config)
char **manifest)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@ -15252,15 +15252,15 @@ postgres_get_extension_config (void *cls,
bool is_null;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_string ("config",
config),
GNUNET_PQ_result_spec_string ("manifest",
manifest),
&is_null),
GNUNET_PQ_result_spec_end
};
*config = NULL;
*manifest = NULL;
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_extension_config",
"get_extension_manifest",
params,
rs);
}
@ -17231,10 +17231,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &postgres_release_revolving_shard;
plugin->delete_shard_locks
= &postgres_delete_shard_locks;
plugin->set_extension_config
= &postgres_set_extension_config;
plugin->get_extension_config
= &postgres_get_extension_config;
plugin->set_extension_manifest
= &postgres_set_extension_manifest;
plugin->get_extension_manifest
= &postgres_get_extension_manifest;
plugin->insert_partner
= &postgres_insert_partner;
plugin->insert_contract

View File

@ -112,53 +112,53 @@ mark_prepare_cb (void *cls,
* Simple check that config retrieval and setting for extensions work
*/
static enum GNUNET_GenericReturnValue
test_extension_config (void)
test_extension_manifest (void)
{
char *config;
char *manifest;
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->get_extension_config (plugin->cls,
plugin->get_extension_manifest (plugin->cls,
"fnord",
&config));
&manifest));
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->set_extension_config (plugin->cls,
plugin->set_extension_manifest (plugin->cls,
"fnord",
"bar"));
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_extension_config (plugin->cls,
plugin->get_extension_manifest (plugin->cls,
"fnord",
&config));
&manifest));
FAILIF (0 != strcmp ("bar", config));
GNUNET_free (config);
FAILIF (0 != strcmp ("bar", manifest));
GNUNET_free (manifest);
/* let's do this again! */
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->set_extension_config (plugin->cls,
plugin->set_extension_manifest (plugin->cls,
"fnord",
"buzz"));
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_extension_config (plugin->cls,
plugin->get_extension_manifest (plugin->cls,
"fnord",
&config));
&manifest));
FAILIF (0 != strcmp ("buzz", config));
GNUNET_free (config);
FAILIF (0 != strcmp ("buzz", manifest));
GNUNET_free (manifest);
/* let's do this again, with NULL */
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->set_extension_config (plugin->cls,
plugin->set_extension_manifest (plugin->cls,
"fnord",
NULL));
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_extension_config (plugin->cls,
plugin->get_extension_manifest (plugin->cls,
"fnord",
&config));
&manifest));
FAILIF (NULL != config);
FAILIF (NULL != manifest);
return GNUNET_OK;
drop:
@ -1272,7 +1272,7 @@ run (void *cls)
NULL));
/* simple extension check */
FAILIF (GNUNET_OK !=
test_extension_config ());
test_extension_manifest ());
RND_BLK (&reserve_pub);
GNUNET_assert (GNUNET_OK ==

View File

@ -22,7 +22,7 @@ libtaler_extension_age_restriction_la_LDFLAGS = \
-no-undefined
libtaler_extension_age_restriction_la_SOURCES = \
extension_age_restriction.c
age_restriction.c
libtaler_extension_age_restriction_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
* @file extension_age_restriction.c
* @file age_restriction.c
* @brief Utility functions regarding age restriction
* @author Özgür Kesim
*/
@ -51,26 +51,19 @@ age_restriction_disable (
ext->enabled = false;
ext->config = NULL;
if (NULL != ext->config_json)
{
json_decref (ext->config_json);
ext->config_json = NULL;
}
AR_config.enabled = false;
AR_config.mask.bits = 0;
AR_config.num_groups = 0;
}
/**
* @brief implements the TALER_Extension.load_json_config interface.
* @brief implements the TALER_Extension.load_config interface.
*
* @param ext if NULL, only tests the configuration
* @param jconfig the configuration as json
*/
static enum GNUNET_GenericReturnValue
age_restriction_load_json_config (
age_restriction_load_config (
struct TALER_Extension *ext,
json_t *jconfig)
{
@ -98,14 +91,8 @@ age_restriction_load_json_config (
AR_config.num_groups = __builtin_popcount (mask.bits) - 1;
}
AR_config.enabled = true;
ext->config = &AR_config;
if (NULL != ext->config_json)
json_decref (ext->config_json);
ext->enabled = true;
ext->config_json = json_copy (jconfig);
json_decref (jconfig);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@ -117,13 +104,13 @@ age_restriction_load_json_config (
/**
* @brief implements the TALER_Extension.config_to_json interface.
* @brief implements the TALER_Extension.manifest interface.
*
* @param ext if NULL, only tests the configuration
* @return configuration as json_t* object, maybe NULL
*/
static json_t *
age_restriction_config_to_json (
age_restriction_manifest (
const struct TALER_Extension *ext)
{
char *mask_str;
@ -131,13 +118,6 @@ age_restriction_config_to_json (
GNUNET_assert (NULL != ext);
if (! ext->enabled)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"age restriction not enabled");
return json_null ();
}
if (NULL == ext->config)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@ -145,11 +125,6 @@ age_restriction_config_to_json (
return json_null ();
}
if (NULL != ext->config_json)
{
return json_copy (ext->config_json);
}
mask_str = TALER_age_mask_to_string (&AR_config.mask);
conf = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("age_groups", mask_str)
@ -165,36 +140,19 @@ age_restriction_config_to_json (
}
/**
* @brief implements the TALER_Extension.test_json_config interface.
*
* @param config configuration as json_t* to test
* @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise.
*/
static enum GNUNET_GenericReturnValue
age_restriction_test_json_config (
const json_t *config)
{
struct TALER_AgeMask mask = {0};
return TALER_JSON_parse_age_groups (config, &mask);
}
/* The extension for age restriction */
struct TALER_Extension TE_extension_age_restriction = {
struct TALER_Extension TE_age_restriction = {
.type = TALER_Extension_AgeRestriction,
.name = "age_restriction",
.critical = false,
.version = "1",
.enabled = false, /* disabled per default */
.has_config = true, /* we need to store configuration */
.config = NULL,
.config_json = NULL,
.disable = &age_restriction_disable,
.test_json_config = &age_restriction_test_json_config,
.load_json_config = &age_restriction_load_json_config,
.config_to_json = &age_restriction_config_to_json,
.load_config = &age_restriction_load_config,
.manifest = &age_restriction_manifest,
.deposit_handler = NULL,
.http_get_handler = NULL,
.http_post_handler = NULL,
};
@ -261,23 +219,20 @@ libtaler_extension_age_restriction_init (void *arg)
AR_config.mask = mask;
AR_config.num_groups = __builtin_popcount (mask.bits) - 1; /* no underflow, first bit always set */
AR_config.enabled = true;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"[age restriction] setting age mask to %s with #groups: %d\n",
TALER_age_mask_to_string (&AR_config.mask),
__builtin_popcount (AR_config.mask.bits) - 1);
TE_extension_age_restriction.config = &AR_config;
TE_extension_age_restriction.enabled = true;
TE_age_restriction.config = &AR_config;
/* Note: we do now have TE_age_restriction_config set, however
* ext->config_json is NOT set, i.e. the extension is not yet active! For
* age restriction to become active, load_json_config must have been
* called. */
/* Note: we do now have TE_age_restriction_config set, however the extension
* is not yet enabled! For age restriction to become active, load_config must
* have been called. */
GNUNET_free (groups);
return &TE_extension_age_restriction;
return &TE_age_restriction;
}
@ -292,11 +247,10 @@ libtaler_extension_age_restriction_done (void *arg)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"[age restriction] disabling and unloading");
AR_config.enabled = 0;
AR_config.mask.bits = 0;
AR_config.num_groups = 0;
return NULL;
}
/* end of extension_age_restriction.c */
/* end of age_restriction.c */

View File

@ -61,8 +61,7 @@ TALER_extensions_get_age_restriction_mask ()
ext = TALER_extensions_get_by_type (TALER_Extension_AgeRestriction);
if ((NULL == ext) ||
(NULL == ext->config) ||
(! ext->enabled))
(NULL == ext->config))
return (struct TALER_AgeMask) {0}
;

View File

@ -46,9 +46,8 @@ add_extension (
(NULL == extension->name) ||
(NULL == extension->version) ||
(NULL == extension->disable) ||
(NULL == extension->test_json_config) ||
(NULL == extension->load_json_config) ||
(NULL == extension->config_to_json))
(NULL == extension->load_config) ||
(NULL == extension->manifest))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"invalid extension\n");
@ -138,20 +137,20 @@ TALER_extensions_get_by_name (
enum GNUNET_GenericReturnValue
TALER_extensions_verify_json_config_signature (
json_t *extensions,
TALER_extensions_verify_manifests_signature (
json_t *manifests,
struct TALER_MasterSignatureP *extensions_sig,
struct TALER_MasterPublicKeyP *master_pub)
{
struct TALER_ExtensionConfigHashP h_config;
struct TALER_ExtensionManifestsHashP h_manifests;
if (GNUNET_OK !=
TALER_JSON_extensions_config_hash (extensions,
&h_config))
TALER_JSON_extensions_manifests_hash (manifests,
&h_manifests))
return GNUNET_SYSERR;
if (GNUNET_OK !=
TALER_exchange_offline_extension_config_hash_verify (
&h_config,
TALER_exchange_offline_extension_manifests_hash_verify (
&h_manifests,
master_pub,
extensions_sig))
return GNUNET_NO;
@ -240,7 +239,7 @@ configure_extension (
static bool extensions_loaded = false;
enum GNUNET_GenericReturnValue
TALER_extensions_load (
TALER_extensions_init (
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
struct LoadConfClosure col = {
@ -263,7 +262,7 @@ TALER_extensions_load (
enum GNUNET_GenericReturnValue
TALER_extensions_is_json_config (
TALER_extensions_parse_manifest (
json_t *obj,
int *critical,
const char **version,
@ -296,22 +295,21 @@ TALER_extensions_is_json_config (
enum GNUNET_GenericReturnValue
TALER_extensions_load_json_config (
TALER_extensions_load_manifests (
json_t *extensions)
{
const char*name;
json_t *blob;
json_t *manifest;
GNUNET_assert (NULL != extensions);
GNUNET_assert (json_is_object (extensions));
json_object_foreach (extensions, name, blob)
json_object_foreach (extensions, name, manifest)
{
int critical;
const char *version;
json_t *config;
const struct TALER_Extension *extension =
TALER_extensions_get_by_name (name);
struct TALER_Extension *extension = (struct TALER_Extension *)TALER_extensions_get_by_name (name);
if (NULL == extension)
{
@ -322,21 +320,22 @@ TALER_extensions_load_json_config (
/* load and verify criticality, version, etc. */
if (GNUNET_OK !=
TALER_extensions_is_json_config (
blob, &critical, &version, &config))
TALER_extensions_parse_manifest (
manifest, &critical, &version, &config))
return GNUNET_SYSERR;
if (critical != extension->critical
|| 0 != strcmp (version, extension->version) // TODO: libtool compare?
|| NULL == config
|| GNUNET_OK != extension->test_json_config (config))
|| GNUNET_OK != extension->load_config (NULL, config))
return GNUNET_SYSERR;
/* This _should_ work now */
if (GNUNET_OK !=
extension->load_json_config ((struct TALER_Extension *) extension,
config))
extension->load_config ( extension, config))
return GNUNET_SYSERR;
extension->enabled = true;
}
/* make sure to disable all extensions that weren't mentioned in the json */

View File

@ -16,16 +16,16 @@ endif
plugindir = $(libdir)/taler
plugin_LTLIBRARIES = \
libtaler_extension_policy_auction.la
libtaler_extension_policy_brandt_vickrey_auction.la
libtaler_extension_policy_auction_la_LDFLAGS = \
libtaler_extension_policy_brandt_vickrey_auction_la_LDFLAGS = \
-version-info 0:0:0 \
-no-undefined
libtaler_extension_policy_auction_la_SOURCES = \
policy_auction.c
libtaler_extension_policy_brandt_vickrey_auction_la_SOURCES = \
policy_brandt_vickrey_auction.c
libtaler_extension_policy_auction_la_LIBADD = \
libtaler_extension_policy_brandt_vickrey_auction_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetjson \

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
* @file policy_auction.c
* @file policy_brandt_vickery_auction.c
* @brief Extension for replay of auctions of type Brandt
* @author Özgür Kesim
*/
@ -26,13 +26,26 @@
#include "stdint.h"
#include <microhttpd.h>
#define POLICY_AUCTION "policy_auction"
#define LOG_PREFIX "[policy_auction] "
#define POLICY_AUCTION "policy_brandt_vickery_auction"
#define LOG_PREFIX "[policy_brandt_vickery_auction] "
#define MAX_RESULT_SIZE 10 * 1024
/* (public) configuration of this extension */
/* TODO: these fields need to be set in the init handler */
static struct TALER_BrandtVickreyAuction BV_config = {
.max_bidders = 10,
.max_prices = 10,
.auction_fee = {
.value = 0,
.fraction = 0,
.currency = {'E', 'U', 'R', 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
};
/* Path to the replay program. */
static char *replay_program;
/* supported currency */
static char *currency;
@ -123,45 +136,6 @@ json_error (json_t **output,
return GNUNET_SYSERR;
};
/**
* @brief returns an JSON with the result
*/
#if 0
static enum GNUNET_GenericReturnValue
json_result (json_t **output,
const struct transcript *tr)
{
json_t *results;
GNUNET_assert (NULL != tr);
*output = json_object ();
results = json_array ();
GNUNET_assert (*output);
GNUNET_assert (results);
for (size_t i = 0; i < tr->results_len; i++)
{
json_t *result = json_pack ("{s:i, s:s}",
"bidder", tr->results[i].bidder,
"price", tr->results[i].price);
GNUNET_assert (result);
GNUNET_assert (-1 !=
json_array_append_new (results, result));
}
GNUNET_assert (-1 !=
json_object_set_new (*output,
"winners",
results));
return GNUNET_OK;
}
#endif
/*
* @brief Parses a given json as transcript.
@ -508,55 +482,49 @@ static void
auction_disable (
struct TALER_Extension *ext)
{
/* TODO: cleanup configuration */
ext->config = NULL;
ext->enabled = false;
}
/**
* @brief implements the TALER_Extension.test_json_config interface.
*
* @param config configuration as json_t* to test
* @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise.
*/
static enum GNUNET_GenericReturnValue
auction_test_json_config (
const json_t *config)
{
/* This extension has no configuration */
return GNUNET_OK;
}
/**
* @brief implements the TALER_Extension.config_to_json interface.
* @brief implements the TALER_Extension.manifest interface.
*
* @param ext if NULL, only tests the configuration
* @return configuration as json_t* object, maybe NULL
*/
static json_t *
auction_config_to_json (
auction_manifest (
const struct TALER_Extension *ext)
{
/* TODO: add configuration */
struct TALER_BrandtVickreyAuction *conf = ext->config;
GNUNET_assert (conf);
json_t *config = GNUNET_JSON_PACK (
GNUNET_JSON_pack_int64 ("max_bidders", conf->max_bidders),
GNUNET_JSON_pack_int64 ("max_prices", conf->max_prices),
TALER_JSON_pack_amount ("auction_fee", &conf->auction_fee));
GNUNET_assert (config);
return GNUNET_JSON_PACK (
GNUNET_JSON_pack_bool ("critical", ext->critical),
GNUNET_JSON_pack_string ("version", ext->version));
GNUNET_JSON_pack_string ("version", ext->version),
GNUNET_JSON_pack_object_steal ("config", config));
}
/**
* @brief implements the TALER_Extension.load_json_config interface.
* @brief implements the TALER_Extension.load_config interface.
*
* @param ext if NULL, only tests the configuration
* @param jconfig the configuration as json
*/
static enum GNUNET_GenericReturnValue
auction_load_json_config (
auction_load_config (
struct TALER_Extension *ext,
json_t *jconfig)
{
/* TODO: add configuration */
/* TODO: parse configuration */
ext->enabled = true;
return GNUNET_OK;
}
@ -620,20 +588,36 @@ auction_http_post_handler (
}
/**
* @brief implements the TALER_Extensions.deposit_handler interface.
*
* @param[in] input JSON input from the client during a deposit request
* @param[out] output by this extension
* @return GNUNET_OK if the request was OK
*/
enum GNUNET_GenericReturnValue
auction_deposit_handler (
json_t *input,
json_t **output)
{
/* TODO */
*output = NULL;
return GNUNET_OK;
}
/* The extension struct for auctions of brandt-style */
struct TALER_Extension TE_auction_brandt = {
.type = TALER_Extension_PolicyAuction,
.type = TALER_Extension_PolicyBrandtVickeryAuction,
.name = POLICY_AUCTION,
.critical = false,
.version = "0",
.enabled = false, /* disabled per default */
.has_config = true,
.config = NULL,
.config_json = NULL,
.config = &BV_config,
.disable = &auction_disable,
.test_json_config = &auction_test_json_config,
.load_json_config = &auction_load_json_config,
.config_to_json = &auction_config_to_json,
.load_config = &auction_load_config,
.manifest = &auction_manifest,
.deposit_handler = &auction_deposit_handler,
.http_get_handler = &auction_http_get_handler,
.http_post_handler = &auction_http_post_handler,
};
@ -653,7 +637,7 @@ struct TALER_Extension TE_auction_brandt = {
* @return Pointer to TE_auction_brandt
*/
struct TALER_Extension *
libtaler_extension_policy_auction_init (void *arg)
libtaler_extension_policy_brandt_vickery_auction_init (void *arg)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
@ -705,7 +689,6 @@ libtaler_extension_policy_auction_init (void *arg)
/* TODO: read other config parameters and generate configuration */
return &TE_auction_brandt;
}
@ -718,7 +701,7 @@ libtaler_extension_policy_auction_init (void *arg)
* @return null
*/
void *
libtaler_extension_policy_auction_done (void *arg)
libtaler_extension_policy_brandt_vickery_auction_done (void *arg)
{
auction_disable (&TE_auction_brandt);
GNUNET_free (replay_program);
@ -728,4 +711,4 @@ libtaler_extension_policy_auction_done (void *arg)
}
/* end of policy_auction.c */
/* end of policy_brandt_vickery_auction.c */

View File

@ -0,0 +1,15 @@
# Basic escrow extension
- on deposit, coins can be put into escrow
- timeout will be specified
- target payto-URL
- public key for release
- returns escrow ID == hash of the coins.
- /extension/escrow endpoint
- post request requires of escrow ID
- signature of the release-key and all coins nedded
- transfere to target-payto-URL.
- on timeout:
- coins are unblocked

View File

@ -727,10 +727,10 @@ struct TALER_PickupIdentifierP
/**
* @brief Salted hash over the JSON object representing the configuration of an
* extension.
* @brief Salted hash over the JSON object representing the manifests of
* extensions.
*/
struct TALER_ExtensionConfigHashP
struct TALER_ExtensionManifestsHashP
{
/**
* Actual hash value.
@ -5242,31 +5242,31 @@ TALER_merchant_contract_sign (
/* **************** /management/extensions offline signing **************** */
/**
* Create a signature for the hash of the configuration of an extension
* Create a signature for the hash of the manifests of extensionss
*
* @param h_config hash of the JSON object representing the configuration
* @param h_manifests hash of the JSON object representing the manifests
* @param master_priv private key to sign with
* @param[out] master_sig where to write the signature
*/
void
TALER_exchange_offline_extension_config_hash_sign (
const struct TALER_ExtensionConfigHashP *h_config,
TALER_exchange_offline_extension_manifests_hash_sign (
const struct TALER_ExtensionManifestsHashP *h_manifests,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig);
/**
* Verify the signature in @a master_sig of the given hash, taken over the JSON
* blob representing the configuration of an extension
* blob representing the manifests of extensions
*
* @param h_config hash of the JSON blob of a configuration of an extension
* @param h_manifests hash of the JSON blob of a configuration of an extension
* @param master_pub master public key of the exchange
* @param master_sig signature of the exchange
* @return #GNUNET_OK if signature is valid
*/
enum GNUNET_GenericReturnValue
TALER_exchange_offline_extension_config_hash_verify (
const struct TALER_ExtensionConfigHashP *h_config,
TALER_exchange_offline_extension_manifests_hash_verify (
const struct TALER_ExtensionManifestsHashP *h_manifests,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig
);

View File

@ -5175,23 +5175,23 @@ struct TALER_EXCHANGEDB_Plugin
/**
* Function called to save the configuration of an extension
* (age-restriction, peer2peer, ...)
* Function called to save the manifest of an extension
* (age_restriction, policy_merchant_refund, ...)
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param extension_name the name of the extension
* @param config JSON object of the configuration as string, maybe NULL (== disabled extension)
* @param manifest Manifest of the extension encoded as JSON object, maybe NULL (== disabled extension)
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*set_extension_config)(void *cls,
(*set_extension_manifest)(void *cls,
const char *extension_name,
const char *config);
/**
* Function called to retrieve the configuration of an extension
* (age-restriction, peer2peer, ...)
* Function called to retrieve the manifest of an extension
* (age_restriction, policy_merchant_refund, ...)
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param extension_name the name of the extension
@ -5199,9 +5199,9 @@ struct TALER_EXCHANGEDB_Plugin
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*get_extension_config)(void *cls,
(*get_extension_manifest)(void *cls,
const char *extension_name,
char **config);
char **manifest);
/**

View File

@ -32,9 +32,9 @@
enum TALER_Extension_Type
{
TALER_Extension_AgeRestriction = 0,
TALER_Extension_PolicyRefund = 1,
TALER_Extension_PolicyAuction = 2,
TALER_Extension_PolicyEscrow = 3,
TALER_Extension_PolicyMerchantRefund = 1,
TALER_Extension_PolicyBrandtVickeryAuction = 2,
TALER_Extension_PolicyEscrowedPayment = 3,
TALER_Extension_MaxPredefined = 4 // Must be last of the predefined
};
@ -52,42 +52,149 @@ struct TALER_Extensions
/*
* @brief Represents the implementation of an extension.
*
* TODO: add documentation
* An "Extension" is an optional feature for the Exchange.
* There are only two types of extensions:
*
* a) Age restriction: This is a special feature that directly interacts with
* denominations and coins, but is not define policies during deposits, see b).
* The implementation of this extension doesn't have to implement any of the
* http- or depost-handlers in the struct.
*
* b) Policies for deposits: These are extensions that define policies (such
* as refund, escrow or auctions) for deposit requests. These extensions have
* to implement at least the deposit- and post-http-handler in the struct to be
* functional.
*
* In addition to the handlers defined in this struct, an extension must also
* be a plugin in the GNUNET_Plugin sense. That is, it must implement the
* functions
* 1: (void *ext)libtaler_extension_<name>_init(void *cfg)
* and
* 2: (void *)libtaler_extension_<name>_done(void *)
*
* In 1:, the input will be the GNUNET_CONFIGURATION_Handle to the TALER
* configuration and the output must be the struct TALER_Extension * on
* success, NULL otherwise.
*
* In 2:, no arguments are passed and NULL is expected to be returned.
*/
struct TALER_Extension
{
/**
* Type of the extension. Only one extension of a type can be loaded
* at any time.
*/
enum TALER_Extension_Type type;
char *name;
bool critical;
char *version;
void *config;
bool enabled;
bool has_config; /* some extension might not have a configuration */
json_t *config_json;
/**
* The name of the extension, must be unique among all loaded extensions. It
* is used in URLs for /extension/$NAME as well.
*/
char *name;
/**
* Criticality of the extension. It has the same semantics as "critical" has
* for extensions in X.509:
* - if "true", the client must "understand" the extension before proceeding,
* - if "false", clients can safely skip extensions they do not understand.
* (see https://datatracker.ietf.org/doc/html/rfc5280#section-4.2)
*/
bool critical;
/**
* Version of the extension must be provided in Taler's protocol verison ranges notation, see
* https://docs.taler.net/core/api-common.html#protocol-version-ranges
*/
char *version;
/**
* If the extension is marked as enabled, it will be listed in the
* "extensions" field in the "/keys" response.
*/
bool enabled;
/**
* Opaque (public) configuration object, set by the extension.
*/
void *config;
/**
* @brief Handler to to disable the extension.
*
* @param ext The current extension object
*/
void (*disable)(struct TALER_Extension *ext);
enum GNUNET_GenericReturnValue (*test_json_config)(
const json_t *config);
enum GNUNET_GenericReturnValue (*load_json_config)(
/**
* @brief Handler to read an extension-specific configuration in JSON
* encoding and enable the extension. Must be implemented by the extension.
*
* @param ext The extension object. If NULL, the configuration will only be checked.
* @param config A JSON blob
* @return GNUNET_OK if the json was a valid configuration for the extension.
*/
enum GNUNET_GenericReturnValue (*load_config)(
struct TALER_Extension *ext,
json_t *config);
json_t *(*config_to_json)(
/**
* @brief Handler to return the manifest of the extension in JSON encoding.
*
* See
* https://docs.taler.net/design-documents/006-extensions.html#tsref-type-Extension
* for the definition.
*
* @param ext The extension object
* @return The JSON encoding of the extension, if enabled, NULL otherwise.
*/
json_t *(*manifest)(
const struct TALER_Extension *ext);
/**
* @brief Handler for /{batch}-deposit requests. Can be NULL.
*
* When a deposit request refers to this extension in its policy
* (see https://docs.taler.net/core/api-exchange.html#deposit), this handler
* will be called during the deposit operation.
*
* @param[in] input The policy/extension specific data, provided by the client in
* the policy-field of the deposit request.
* @param[out] output Potential output by the extension to be provided to the
* client as part of the response to the deposit request. Can be NULL.
* @return GNUNET_OK if the data was accepted by the extension.
*/
enum GNUNET_GenericReturnValue (*deposit_handler)(
json_t *input,
json_t **output);
/**
* @brief Handler for POST-requests to the /policy/$name endpoint. Can be NULL.
*
* @param connection The current connection
* @param root The JSON body from the request
* @param args Additional query parameters of the request.
* @return MDH result
*/
MHD_RESULT (*http_post_handler)(
struct MHD_Connection *connection,
const json_t *root,
const char *const args[]);
/**
* @brief Handler for GET-requests to the /policy/$name endpoint. Can be NULL.
*
* @param connection The current connection
* @param root The JSON body from the request
* @param args Additional query parameters of the request.
* @return MDH result
*/
MHD_RESULT (*http_get_handler)(
struct MHD_Connection *connection,
const char *const args[]);
};
/**
* Generic functions for extensions
*/
@ -101,39 +208,38 @@ struct TALER_Extension
* or any particular configuration couldn't be parsed.
*/
enum GNUNET_GenericReturnValue
TALER_extensions_load (
TALER_extensions_init (
const struct GNUNET_CONFIGURATION_Handle *cfg);
/*
* @brief Checks the given obj to be a valid extension object and fill the
* fields accordingly.
* @brief Parses a given JSON object as an extension manifest.
*
* @param[in] obj Object to verify is a valid extension
* @param[in] obj JSON object to parse as an extension manifest
* @param{out] critical will be set to 1 if the extension is critical according to obj
* @param[out] version will be set to the version of the extension according to obj
* @param[out] config will be set to the configuration of the extension according to obj
* @return OK on success, Error otherwise
*/
enum GNUNET_GenericReturnValue
TALER_extensions_is_json_config (
TALER_extensions_parse_manifest (
json_t *obj,
int *critical,
const char **version,
json_t **config);
/*
* @brief Sets the configuration of the extensions from a given JSON object.
* @brief Loads extensions according to the manifests.
*
* The JSON object must be of type ExchangeKeysResponse as described in
* https://docs.taler.net/design-documents/006-extensions.html#exchange
* The JSON object must be of type ExtensionsManifestsResponse as described
* in https://docs.taler.net/design-documents/006-extensions.html#exchange
*
* @param cfg JSON object containing the configuration for all extensions
* @param cfg JSON object containing the manifests for all extensions
* @return #GNUNET_OK on success, #GNUNET_SYSERR if unknown extensions were
* found or any particular configuration couldn't be parsed.
*/
enum GNUNET_GenericReturnValue
TALER_extensions_load_json_config (
json_t *cfg);
TALER_extensions_load_manifests (
json_t *manifests);
/*
* @brief Returns the head of the linked list of extensions.
@ -186,7 +292,7 @@ TALER_extensions_is_enabled (
* Verify the signature of a given JSON object for extensions with the master
* key of the exchange.
*
* The JSON object must be of type ExchangeKeysResponse as described in
* The JSON object must be of type ExtensionsManifestsResponse as described in
* https://docs.taler.net/design-documents/006-extensions.html#exchange
*
* @param extensions JSON object with the extension configuration
@ -196,8 +302,8 @@ TALER_extensions_is_enabled (
* and GNUNET_NO if the signature couldn't be verified.
*/
enum GNUNET_GenericReturnValue
TALER_extensions_verify_json_config_signature (
json_t *extensions,
TALER_extensions_verify_manifests_signature (
json_t *manifests,
struct TALER_MasterSignatureP *extensions_sig,
struct TALER_MasterPublicKeyP *master_pub);
@ -207,6 +313,8 @@ TALER_extensions_verify_json_config_signature (
*
* This extension is special insofar as it directly interacts with coins and
* denominations.
*
* At the same time, it doesn't implement and http- or deposit-handlers.
*/
#define TALER_EXTENSION_SECTION_AGE_RESTRICTION (TALER_EXTENSION_SECTION_PREFIX \
@ -228,7 +336,6 @@ TALER_extensions_verify_json_config_signature (
*/
struct TALER_AgeRestrictionConfig
{
bool enabled;
struct TALER_AgeMask mask;
uint8_t num_groups;
};
@ -260,7 +367,18 @@ TALER_extensions_get_age_restriction_mask ();
/*
* TODO: Add Peer2Peer Extension
* ================================
* Brandt-Vickrey Auctions
* ================================
*/
/*
* @brief Configuration for Brandt-Vickrey auctions
*/
struct TALER_BrandtVickreyAuction
{
uint16_t max_bidders;
uint16_t max_prices;
struct TALER_Amount auction_fee;
};
#endif

View File

@ -779,13 +779,13 @@ TALER_deposit_extension_hash (const json_t *extensions,
/**
* Hash the @a config of an extension, given as JSON
*
* @param config configuration of the extension
* @param manifests manifests of extensions
* @param[out] eh where to write the extension hash
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
*/
enum GNUNET_GenericReturnValue
TALER_JSON_extensions_config_hash (const json_t *config,
struct TALER_ExtensionConfigHashP *eh);
TALER_JSON_extensions_manifests_hash (const json_t *manifests,
struct TALER_ExtensionManifestsHashP *eh);
/**
* Canonicalize a JSON input to a string according to RFC 8785.

View File

@ -1037,10 +1037,10 @@ TALER_JSON_canonicalize (const json_t *input)
enum GNUNET_GenericReturnValue
TALER_JSON_extensions_config_hash (const json_t *config,
struct TALER_ExtensionConfigHashP *ech)
TALER_JSON_extensions_manifests_hash (const json_t *manifests,
struct TALER_ExtensionManifestsHashP *ech)
{
return dump_and_hash (config,
return dump_and_hash (manifests,
"taler-extension-configuration",
&ech->hash);
}

View File

@ -897,18 +897,18 @@ decode_keys_json (const json_t *resp_obj,
}
}
/* Parse the supported extension(s): age-restriction. */
/* Parse the supported extension(s): age_restriction. */
/* TODO: maybe lift all this into a FP in TALER_Extension ? */
{
struct TALER_MasterSignatureP extensions_sig = {0};
json_t *extensions = NULL;
json_t *manifests = NULL;
bool no_extensions = false;
bool no_signature = false;
struct GNUNET_JSON_Specification ext_spec[] = {
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("extensions",
&extensions),
&manifests),
&no_extensions),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto (
@ -933,14 +933,14 @@ decode_keys_json (const json_t *resp_obj,
{
/* 2. We have an extensions object. Verify its signature. */
EXITIF (GNUNET_OK !=
TALER_extensions_verify_json_config_signature (
extensions,
TALER_extensions_verify_manifests_signature (
manifests,
&extensions_sig,
&key_data->master_pub));
/* 3. Parse and set the the configuration of the extensions accordingly */
EXITIF (GNUNET_OK !=
TALER_extensions_load_json_config (extensions));
TALER_extensions_load_manifests (manifests));
}
/* 4. assuming we might have now a new value for age_mask, set it in key_data */

2531
src/testing/exec Normal file

File diff suppressed because it is too large Load Diff

3224
src/testing/fnord Normal file

File diff suppressed because it is too large Load Diff

26187
src/testing/keys-cs.json Normal file

File diff suppressed because it is too large Load Diff

2177
src/testing/keys-rsa.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -93,9 +93,9 @@ HTTP_PORT = 9081
#AGE_GROUPS = "8:10:12:14:16:18:21"
# Enable policy of type auction for deposits.
[exchange-extension-policy_auction]
[exchange-extension-policy_brandt_vickrey_auction]
ENABLED = YES
REPLAY_PROGRAM = "/usr/local/bin/taler-exchange-auction_brandt-replay"
REPLAY_PROGRAM = "/usr/local/bin/brandt_vickrey_auction-replay"
# Sections starting with "coin_" specify which denominations
# the exchange should support (and their respective fee structure)

View File

@ -315,7 +315,7 @@ sign_keys_for_exchange (void *cls,
int ret;
/* Load the extensions */
if (GNUNET_OK != TALER_extensions_load (cfg))
if (GNUNET_OK != TALER_extensions_init (cfg))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"couldn't load extensions");
@ -716,7 +716,7 @@ TALER_TESTING_setup_with_exchange_cfg (
int result;
/* Load extensions */
if (GNUNET_OK != TALER_extensions_load (cfg))
if (GNUNET_OK != TALER_extensions_init (cfg))
return GNUNET_SYSERR;
if (GNUNET_OK !=

View File

@ -942,7 +942,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
* @brief Signature made by the exchange offline key over the
* configuration of an extension.
*/
struct TALER_MasterExtensionConfigurationPS
struct TALER_MasterExtensionManifestsPS
{
/**
* Purpose is #TALER_SIGNATURE_MASTER_EXTENSION. Signed
@ -953,22 +953,22 @@ struct TALER_MasterExtensionConfigurationPS
/**
* Hash of the JSON object that represents the configuration of an extension.
*/
struct TALER_ExtensionConfigHashP h_config GNUNET_PACKED;
struct TALER_ExtensionManifestsHashP h_manifests GNUNET_PACKED;
};
GNUNET_NETWORK_STRUCT_END
void
TALER_exchange_offline_extension_config_hash_sign (
const struct TALER_ExtensionConfigHashP *h_config,
TALER_exchange_offline_extension_manifests_hash_sign (
const struct TALER_ExtensionManifestsHashP *h_manifests,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
{
struct TALER_MasterExtensionConfigurationPS ec = {
struct TALER_MasterExtensionManifestsPS ec = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
.purpose.size = htonl (sizeof(ec)),
.h_config = *h_config
.h_manifests = *h_manifests
};
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
&ec,
@ -977,16 +977,16 @@ TALER_exchange_offline_extension_config_hash_sign (
enum GNUNET_GenericReturnValue
TALER_exchange_offline_extension_config_hash_verify (
const struct TALER_ExtensionConfigHashP *h_config,
TALER_exchange_offline_extension_manifests_hash_verify (
const struct TALER_ExtensionManifestsHashP *h_manifests,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig
)
{
struct TALER_MasterExtensionConfigurationPS ec = {
struct TALER_MasterExtensionManifestsPS ec = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
.purpose.size = htonl (sizeof(ec)),
.h_config = *h_config
.h_manifests = *h_manifests
};
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,