Compare commits

...

4 Commits

33 changed files with 34592 additions and 398 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2198,7 +2198,7 @@ BEGIN
-- FIXME: implement! -- FIXME: implement!
END $$ END $$;
COMMIT; COMMIT;

View File

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

View File

@ -22,7 +22,7 @@ libtaler_extension_age_restriction_la_LDFLAGS = \
-no-undefined -no-undefined
libtaler_extension_age_restriction_la_SOURCES = \ libtaler_extension_age_restriction_la_SOURCES = \
extension_age_restriction.c age_restriction.c
libtaler_extension_age_restriction_la_LIBADD = \ libtaler_extension_age_restriction_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \ $(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/> 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 * @brief Utility functions regarding age restriction
* @author Özgür Kesim * @author Özgür Kesim
*/ */
@ -51,26 +51,19 @@ age_restriction_disable (
ext->enabled = false; ext->enabled = false;
ext->config = NULL; 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.mask.bits = 0;
AR_config.num_groups = 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 ext if NULL, only tests the configuration
* @param jconfig the configuration as json * @param jconfig the configuration as json
*/ */
static enum GNUNET_GenericReturnValue static enum GNUNET_GenericReturnValue
age_restriction_load_json_config ( age_restriction_load_config (
struct TALER_Extension *ext, struct TALER_Extension *ext,
json_t *jconfig) json_t *jconfig)
{ {
@ -98,14 +91,8 @@ age_restriction_load_json_config (
AR_config.num_groups = __builtin_popcount (mask.bits) - 1; AR_config.num_groups = __builtin_popcount (mask.bits) - 1;
} }
AR_config.enabled = true;
ext->config = &AR_config; ext->config = &AR_config;
if (NULL != ext->config_json)
json_decref (ext->config_json);
ext->enabled = true; ext->enabled = true;
ext->config_json = json_copy (jconfig);
json_decref (jconfig); json_decref (jconfig);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 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 * @param ext if NULL, only tests the configuration
* @return configuration as json_t* object, maybe NULL * @return configuration as json_t* object, maybe NULL
*/ */
static json_t * static json_t *
age_restriction_config_to_json ( age_restriction_manifest (
const struct TALER_Extension *ext) const struct TALER_Extension *ext)
{ {
char *mask_str; char *mask_str;
@ -131,13 +118,6 @@ age_restriction_config_to_json (
GNUNET_assert (NULL != ext); GNUNET_assert (NULL != ext);
if (! ext->enabled)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"age restriction not enabled");
return json_null ();
}
if (NULL == ext->config) if (NULL == ext->config)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@ -145,11 +125,6 @@ age_restriction_config_to_json (
return json_null (); return json_null ();
} }
if (NULL != ext->config_json)
{
return json_copy (ext->config_json);
}
mask_str = TALER_age_mask_to_string (&AR_config.mask); mask_str = TALER_age_mask_to_string (&AR_config.mask);
conf = GNUNET_JSON_PACK ( conf = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("age_groups", mask_str) 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 */ /* The extension for age restriction */
struct TALER_Extension TE_extension_age_restriction = { struct TALER_Extension TE_age_restriction = {
.type = TALER_Extension_AgeRestriction, .type = TALER_Extension_AgeRestriction,
.name = "age_restriction", .name = "age_restriction",
.critical = false, .critical = false,
.version = "1", .version = "1",
.enabled = false, /* disabled per default */ .enabled = false, /* disabled per default */
.has_config = true, /* we need to store configuration */
.config = NULL, .config = NULL,
.config_json = NULL,
.disable = &age_restriction_disable, .disable = &age_restriction_disable,
.test_json_config = &age_restriction_test_json_config, .load_config = &age_restriction_load_config,
.load_json_config = &age_restriction_load_json_config, .manifest = &age_restriction_manifest,
.config_to_json = &age_restriction_config_to_json, .deposit_handler = NULL,
.http_get_handler = NULL,
.http_post_handler = NULL, .http_post_handler = NULL,
}; };
@ -261,23 +219,20 @@ libtaler_extension_age_restriction_init (void *arg)
AR_config.mask = mask; AR_config.mask = mask;
AR_config.num_groups = __builtin_popcount (mask.bits) - 1; /* no underflow, first bit always set */ 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, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"[age restriction] setting age mask to %s with #groups: %d\n", "[age restriction] setting age mask to %s with #groups: %d\n",
TALER_age_mask_to_string (&AR_config.mask), TALER_age_mask_to_string (&AR_config.mask),
__builtin_popcount (AR_config.mask.bits) - 1); __builtin_popcount (AR_config.mask.bits) - 1);
TE_extension_age_restriction.config = &AR_config; TE_age_restriction.config = &AR_config;
TE_extension_age_restriction.enabled = true;
/* Note: we do now have TE_age_restriction_config set, however /* Note: we do now have TE_age_restriction_config set, however the extension
* ext->config_json is NOT set, i.e. the extension is not yet active! For * is not yet enabled! For age restriction to become active, load_config must
* age restriction to become active, load_json_config must have been * have been called. */
* called. */
GNUNET_free (groups); 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, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"[age restriction] disabling and unloading"); "[age restriction] disabling and unloading");
AR_config.enabled = 0;
AR_config.mask.bits = 0; AR_config.mask.bits = 0;
AR_config.num_groups = 0; AR_config.num_groups = 0;
return NULL; 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); ext = TALER_extensions_get_by_type (TALER_Extension_AgeRestriction);
if ((NULL == ext) || if ((NULL == ext) ||
(NULL == ext->config) || (NULL == ext->config))
(! ext->enabled))
return (struct TALER_AgeMask) {0} return (struct TALER_AgeMask) {0}
; ;

View File

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

View File

@ -16,16 +16,16 @@ endif
plugindir = $(libdir)/taler plugindir = $(libdir)/taler
plugin_LTLIBRARIES = \ 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 \ -version-info 0:0:0 \
-no-undefined -no-undefined
libtaler_extension_policy_auction_la_SOURCES = \ libtaler_extension_policy_brandt_vickrey_auction_la_SOURCES = \
policy_auction.c 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/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
-lgnunetjson \ -lgnunetjson \

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 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 * @brief Extension for replay of auctions of type Brandt
* @author Özgür Kesim * @author Özgür Kesim
*/ */
@ -26,13 +26,26 @@
#include "stdint.h" #include "stdint.h"
#include <microhttpd.h> #include <microhttpd.h>
#define POLICY_AUCTION "policy_auction" #define POLICY_AUCTION "policy_brandt_vickery_auction"
#define LOG_PREFIX "[policy_auction] " #define LOG_PREFIX "[policy_brandt_vickery_auction] "
#define MAX_RESULT_SIZE 10 * 1024 #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. */ /* Path to the replay program. */
static char *replay_program; static char *replay_program;
/* supported currency */ /* supported currency */
static char *currency; static char *currency;
@ -123,45 +136,6 @@ json_error (json_t **output,
return GNUNET_SYSERR; 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. * @brief Parses a given json as transcript.
@ -508,55 +482,49 @@ static void
auction_disable ( auction_disable (
struct TALER_Extension *ext) struct TALER_Extension *ext)
{ {
/* TODO: cleanup configuration */ ext->config = NULL;
ext->enabled = false; ext->enabled = false;
} }
/** /**
* @brief implements the TALER_Extension.test_json_config interface. * @brief implements the TALER_Extension.manifest 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.
* *
* @param ext if NULL, only tests the configuration * @param ext if NULL, only tests the configuration
* @return configuration as json_t* object, maybe NULL * @return configuration as json_t* object, maybe NULL
*/ */
static json_t * static json_t *
auction_config_to_json ( auction_manifest (
const struct TALER_Extension *ext) 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 ( return GNUNET_JSON_PACK (
GNUNET_JSON_pack_bool ("critical", ext->critical), 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 ext if NULL, only tests the configuration
* @param jconfig the configuration as json * @param jconfig the configuration as json
*/ */
static enum GNUNET_GenericReturnValue static enum GNUNET_GenericReturnValue
auction_load_json_config ( auction_load_config (
struct TALER_Extension *ext, struct TALER_Extension *ext,
json_t *jconfig) json_t *jconfig)
{ {
/* TODO: add configuration */ /* TODO: parse configuration */
ext->enabled = true; ext->enabled = true;
return GNUNET_OK; 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 */ /* The extension struct for auctions of brandt-style */
struct TALER_Extension TE_auction_brandt = { struct TALER_Extension TE_auction_brandt = {
.type = TALER_Extension_PolicyAuction, .type = TALER_Extension_PolicyBrandtVickeryAuction,
.name = POLICY_AUCTION, .name = POLICY_AUCTION,
.critical = false, .critical = false,
.version = "0", .version = "0",
.enabled = false, /* disabled per default */ .enabled = false, /* disabled per default */
.has_config = true, .config = &BV_config,
.config = NULL,
.config_json = NULL,
.disable = &auction_disable, .disable = &auction_disable,
.test_json_config = &auction_test_json_config, .load_config = &auction_load_config,
.load_json_config = &auction_load_json_config, .manifest = &auction_manifest,
.config_to_json = &auction_config_to_json, .deposit_handler = &auction_deposit_handler,
.http_get_handler = &auction_http_get_handler, .http_get_handler = &auction_http_get_handler,
.http_post_handler = &auction_http_post_handler, .http_post_handler = &auction_http_post_handler,
}; };
@ -653,7 +637,7 @@ struct TALER_Extension TE_auction_brandt = {
* @return Pointer to TE_auction_brandt * @return Pointer to TE_auction_brandt
*/ */
struct TALER_Extension * 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; 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 */ /* TODO: read other config parameters and generate configuration */
return &TE_auction_brandt; return &TE_auction_brandt;
} }
@ -718,7 +701,7 @@ libtaler_extension_policy_auction_init (void *arg)
* @return null * @return null
*/ */
void * void *
libtaler_extension_policy_auction_done (void *arg) libtaler_extension_policy_brandt_vickery_auction_done (void *arg)
{ {
auction_disable (&TE_auction_brandt); auction_disable (&TE_auction_brandt);
GNUNET_free (replay_program); 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 * @brief Salted hash over the JSON object representing the manifests of
* extension. * extensions.
*/ */
struct TALER_ExtensionConfigHashP struct TALER_ExtensionManifestsHashP
{ {
/** /**
* Actual hash value. * Actual hash value.
@ -5242,31 +5242,31 @@ TALER_merchant_contract_sign (
/* **************** /management/extensions offline signing **************** */ /* **************** /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 master_priv private key to sign with
* @param[out] master_sig where to write the signature * @param[out] master_sig where to write the signature
*/ */
void void
TALER_exchange_offline_extension_config_hash_sign ( TALER_exchange_offline_extension_manifests_hash_sign (
const struct TALER_ExtensionConfigHashP *h_config, const struct TALER_ExtensionManifestsHashP *h_manifests,
const struct TALER_MasterPrivateKeyP *master_priv, const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig); struct TALER_MasterSignatureP *master_sig);
/** /**
* Verify the signature in @a master_sig of the given hash, taken over the JSON * 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_pub master public key of the exchange
* @param master_sig signature of the exchange * @param master_sig signature of the exchange
* @return #GNUNET_OK if signature is valid * @return #GNUNET_OK if signature is valid
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_exchange_offline_extension_config_hash_verify ( TALER_exchange_offline_extension_manifests_hash_verify (
const struct TALER_ExtensionConfigHashP *h_config, const struct TALER_ExtensionManifestsHashP *h_manifests,
const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig 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 * Function called to save the manifest of an extension
* (age-restriction, peer2peer, ...) * (age_restriction, policy_merchant_refund, ...)
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param extension_name the name of the extension * @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 * @return transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
(*set_extension_config)(void *cls, (*set_extension_manifest)(void *cls,
const char *extension_name, const char *extension_name,
const char *config); const char *config);
/** /**
* Function called to retrieve the configuration of an extension * Function called to retrieve the manifest of an extension
* (age-restriction, peer2peer, ...) * (age_restriction, policy_merchant_refund, ...)
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param extension_name the name of the extension * @param extension_name the name of the extension
@ -5199,9 +5199,9 @@ struct TALER_EXCHANGEDB_Plugin
* @return transaction status code * @return transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
(*get_extension_config)(void *cls, (*get_extension_manifest)(void *cls,
const char *extension_name, const char *extension_name,
char **config); char **manifest);
/** /**

View File

@ -31,11 +31,11 @@
enum TALER_Extension_Type enum TALER_Extension_Type
{ {
TALER_Extension_AgeRestriction = 0, TALER_Extension_AgeRestriction = 0,
TALER_Extension_PolicyRefund = 1, TALER_Extension_PolicyMerchantRefund = 1,
TALER_Extension_PolicyAuction = 2, TALER_Extension_PolicyBrandtVickeryAuction = 2,
TALER_Extension_PolicyEscrow = 3, TALER_Extension_PolicyEscrowedPayment = 3,
TALER_Extension_MaxPredefined = 4 // Must be last of the predefined TALER_Extension_MaxPredefined = 4 // Must be last of the predefined
}; };
@ -52,42 +52,149 @@ struct TALER_Extensions
/* /*
* @brief Represents the implementation of an extension. * @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 struct TALER_Extension
{ {
/**
* Type of the extension. Only one extension of a type can be loaded
* at any time.
*/
enum TALER_Extension_Type type; 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); void (*disable)(struct TALER_Extension *ext);
enum GNUNET_GenericReturnValue (*test_json_config)( /**
const json_t *config); * @brief Handler to read an extension-specific configuration in JSON
* encoding and enable the extension. Must be implemented by the extension.
enum GNUNET_GenericReturnValue (*load_json_config)( *
* @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, struct TALER_Extension *ext,
json_t *config); 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); 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)( MHD_RESULT (*http_post_handler)(
struct MHD_Connection *connection, struct MHD_Connection *connection,
const json_t *root, const json_t *root,
const char *const args[]); 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)( MHD_RESULT (*http_get_handler)(
struct MHD_Connection *connection, struct MHD_Connection *connection,
const char *const args[]); const char *const args[]);
}; };
/** /**
* Generic functions for extensions * Generic functions for extensions
*/ */
@ -101,39 +208,38 @@ struct TALER_Extension
* or any particular configuration couldn't be parsed. * or any particular configuration couldn't be parsed.
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_extensions_load ( TALER_extensions_init (
const struct GNUNET_CONFIGURATION_Handle *cfg); const struct GNUNET_CONFIGURATION_Handle *cfg);
/* /*
* @brief Checks the given obj to be a valid extension object and fill the * @brief Parses a given JSON object as an extension manifest.
* fields accordingly.
* *
* @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] 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] 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 * @param[out] config will be set to the configuration of the extension according to obj
* @return OK on success, Error otherwise * @return OK on success, Error otherwise
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_extensions_is_json_config ( TALER_extensions_parse_manifest (
json_t *obj, json_t *obj,
int *critical, int *critical,
const char **version, const char **version,
json_t **config); 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 * The JSON object must be of type ExtensionsManifestsResponse as described
* https://docs.taler.net/design-documents/006-extensions.html#exchange * 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 * @return #GNUNET_OK on success, #GNUNET_SYSERR if unknown extensions were
* found or any particular configuration couldn't be parsed. * found or any particular configuration couldn't be parsed.
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_extensions_load_json_config ( TALER_extensions_load_manifests (
json_t *cfg); json_t *manifests);
/* /*
* @brief Returns the head of the linked list of extensions. * @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 * Verify the signature of a given JSON object for extensions with the master
* key of the exchange. * 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 * https://docs.taler.net/design-documents/006-extensions.html#exchange
* *
* @param extensions JSON object with the extension configuration * @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. * and GNUNET_NO if the signature couldn't be verified.
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_extensions_verify_json_config_signature ( TALER_extensions_verify_manifests_signature (
json_t *extensions, json_t *manifests,
struct TALER_MasterSignatureP *extensions_sig, struct TALER_MasterSignatureP *extensions_sig,
struct TALER_MasterPublicKeyP *master_pub); 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 * This extension is special insofar as it directly interacts with coins and
* denominations. * denominations.
*
* At the same time, it doesn't implement and http- or deposit-handlers.
*/ */
#define TALER_EXTENSION_SECTION_AGE_RESTRICTION (TALER_EXTENSION_SECTION_PREFIX \ #define TALER_EXTENSION_SECTION_AGE_RESTRICTION (TALER_EXTENSION_SECTION_PREFIX \
@ -228,7 +336,6 @@ TALER_extensions_verify_json_config_signature (
*/ */
struct TALER_AgeRestrictionConfig struct TALER_AgeRestrictionConfig
{ {
bool enabled;
struct TALER_AgeMask mask; struct TALER_AgeMask mask;
uint8_t num_groups; 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 #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 * 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 * @param[out] eh where to write the extension hash
* @return GNUNET_OK on success, GNUNET_SYSERR on failure * @return GNUNET_OK on success, GNUNET_SYSERR on failure
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_JSON_extensions_config_hash (const json_t *config, TALER_JSON_extensions_manifests_hash (const json_t *manifests,
struct TALER_ExtensionConfigHashP *eh); struct TALER_ExtensionManifestsHashP *eh);
/** /**
* Canonicalize a JSON input to a string according to RFC 8785. * 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 enum GNUNET_GenericReturnValue
TALER_JSON_extensions_config_hash (const json_t *config, TALER_JSON_extensions_manifests_hash (const json_t *manifests,
struct TALER_ExtensionConfigHashP *ech) struct TALER_ExtensionManifestsHashP *ech)
{ {
return dump_and_hash (config, return dump_and_hash (manifests,
"taler-extension-configuration", "taler-extension-configuration",
&ech->hash); &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 ? */ /* TODO: maybe lift all this into a FP in TALER_Extension ? */
{ {
struct TALER_MasterSignatureP extensions_sig = {0}; struct TALER_MasterSignatureP extensions_sig = {0};
json_t *extensions = NULL; json_t *manifests = NULL;
bool no_extensions = false; bool no_extensions = false;
bool no_signature = false; bool no_signature = false;
struct GNUNET_JSON_Specification ext_spec[] = { struct GNUNET_JSON_Specification ext_spec[] = {
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("extensions", GNUNET_JSON_spec_json ("extensions",
&extensions), &manifests),
&no_extensions), &no_extensions),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ( 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. */ /* 2. We have an extensions object. Verify its signature. */
EXITIF (GNUNET_OK != EXITIF (GNUNET_OK !=
TALER_extensions_verify_json_config_signature ( TALER_extensions_verify_manifests_signature (
extensions, manifests,
&extensions_sig, &extensions_sig,
&key_data->master_pub)); &key_data->master_pub));
/* 3. Parse and set the the configuration of the extensions accordingly */ /* 3. Parse and set the the configuration of the extensions accordingly */
EXITIF (GNUNET_OK != 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 */ /* 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" #AGE_GROUPS = "8:10:12:14:16:18:21"
# Enable policy of type auction for deposits. # Enable policy of type auction for deposits.
[exchange-extension-policy_auction] [exchange-extension-policy_brandt_vickrey_auction]
ENABLED = YES 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 # Sections starting with "coin_" specify which denominations
# the exchange should support (and their respective fee structure) # the exchange should support (and their respective fee structure)

View File

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

View File

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