aboutsummaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd.c112
-rw-r--r--src/exchange/taler-exchange-httpd.h10
-rw-r--r--src/exchange/taler-exchange-httpd_batch-deposit.c34
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c56
-rw-r--r--src/exchange/taler-exchange-httpd_extensions.c100
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c85
-rw-r--r--src/exchange/taler-exchange-httpd_management_extensions.c36
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c5
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c2
9 files changed, 311 insertions, 129 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 9349a5a2..d97c68e3 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -98,6 +98,14 @@ static int allow_address_reuse;
const struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
/**
+ * Configuration of age restriction
+ *
+ * Set after loading the library, enabled in database event handler.
+ */
+bool TEH_age_restriction_enabled = false;
+struct TALER_AgeRestrictionConfig TEH_age_restriction_config = {0};
+
+/**
* Handle to the HTTP server.
*/
static struct MHD_Daemon *mhd;
@@ -139,11 +147,6 @@ char *TEH_currency;
char *TEH_base_url;
/**
- * Age restriction flags and mask
- */
-bool TEH_age_restriction_enabled = true;
-
-/**
* Default timeout in seconds for HTTP requests.
*/
static unsigned int connection_timeout = 30;
@@ -170,6 +173,7 @@ bool TEH_suicide;
* TALER_SIGNATURE_MASTER_EXTENSION.
*/
struct TALER_MasterSignatureP TEH_extensions_sig;
+bool TEH_extensions_signed = false;
/**
* Value to return from main()
@@ -1039,6 +1043,89 @@ handle_post_auditors (struct TEH_RequestContext *rc,
/**
+ * Handle GET "/extensions/..." requests.
+ *
+ * @param rc request context
+ * @param args array of additional options
+ * @return MHD result code
+ */
+static MHD_RESULT
+handle_get_extensions (struct TEH_RequestContext *rc,
+ const char *const args[])
+{
+ const struct TALER_Extension *ext = NULL;
+
+ if (NULL == args[0])
+ {
+ GNUNET_break_op (0);
+ return r404 (rc->connection,
+ "/extensions/$EXTENSION");
+ }
+
+ ext = TALER_extensions_get_by_name (args[0]);
+ if (NULL == ext)
+ {
+ GNUNET_break_op (0);
+ return r404 (rc->connection,
+ "/extensions/$EXTENSION unknown");
+ }
+
+ if (NULL == ext->http_get_handler)
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_NOT_IMPLEMENTED,
+ TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
+ "GET /extensions/$EXTENSION not supported");
+
+ return ext->http_get_handler (
+ rc->connection,
+ &args[1]);
+}
+
+
+/**
+ * Handle POST "/extensions/..." requests.
+ *
+ * @param rc request context
+ * @param root uploaded JSON data
+ * @param args array of additional options
+ * @return MHD result code
+ */
+static MHD_RESULT
+handle_post_extensions (struct TEH_RequestContext *rc,
+ const json_t *root,
+ const char *const args[])
+{
+ const struct TALER_Extension *ext = NULL;
+
+ if (NULL == args[0])
+ {
+ GNUNET_break_op (0);
+ return r404 (rc->connection,
+ "/extensions/$EXTENSION");
+ }
+
+ ext = TALER_extensions_get_by_name (args[0]);
+ if (NULL == ext)
+ {
+ GNUNET_break_op (0);
+ return r404 (rc->connection,
+ "/extensions/$EXTENSION unknown");
+ }
+
+ if (NULL == ext->http_post_handler)
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_NOT_IMPLEMENTED,
+ TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
+ "POST /extensions/$EXTENSION not supported");
+
+ return ext->http_post_handler (
+ rc->connection,
+ root,
+ &args[1]);
+}
+
+
+/**
* Handle incoming HTTP request.
*
* @param cls closure for MHD daemon (unused)
@@ -1255,6 +1342,21 @@ handle_mhd_request (void *cls,
.nargs = 4,
.nargs_is_upper_bound = true
},
+ /* extensions endpoints */
+ {
+ .url = "extensions",
+ .method = MHD_HTTP_METHOD_GET,
+ .handler.get = &handle_get_extensions,
+ .nargs = 4, /* Arbitrary upper bound */
+ .nargs_is_upper_bound = true,
+ },
+ {
+ .url = "extensions",
+ .method = MHD_HTTP_METHOD_POST,
+ .handler.post = &handle_post_extensions,
+ .nargs = 4, /* Arbitrary upper bound */
+ .nargs_is_upper_bound = true,
+ },
/* mark end of list */
{
.url = NULL
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
index 0fda5ed8..4d3fb490 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -197,11 +197,6 @@ extern struct TALER_EXCHANGEDB_Plugin *TEH_plugin;
*/
extern char *TEH_currency;
-/*
- * Age restriction extension state
- */
-extern bool TEH_age_restriction_enabled;
-
/**
* Our (externally visible) base URL.
*/
@@ -221,6 +216,7 @@ extern struct GNUNET_CURL_Context *TEH_curl_ctx;
* Signature of the offline master key of all enabled extensions' configuration
*/
extern struct TALER_MasterSignatureP TEH_extensions_sig;
+extern bool TEH_extensions_signed;
/**
* @brief Struct describing an URL and the handler for it.
@@ -366,4 +362,8 @@ struct TEH_RequestHandler
};
+/* Age restriction configuration */
+extern bool TEH_age_restriction_enabled;
+extern struct TALER_AgeRestrictionConfig TEH_age_restriction_config;
+
#endif
diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c
index c2a9cbd5..637c8a45 100644
--- a/src/exchange/taler-exchange-httpd_batch-deposit.c
+++ b/src/exchange/taler-exchange-httpd_batch-deposit.c
@@ -87,15 +87,16 @@ struct BatchDepositContext
const char *payto_uri;
/**
- * Additional details for extensions relevant for this
+ * Additional details for policy relevant for this
* deposit operation, possibly NULL!
*/
- json_t *extension_details;
+ json_t *policy_details;
+ bool no_policy_details;
/**
- * Hash over @e extension_details.
+ * Hash over @e policy_details, might be all zero;
*/
- struct TALER_ExtensionContractHashP h_extensions;
+ struct TALER_ExtensionPolicyHashP h_policy;
/**
* Time when this request was generated. Used, for example, to
@@ -173,7 +174,7 @@ again:
&TEH_keys_exchange_sign_,
&bdc->h_contract_terms,
&bdc->h_wire,
- &bdc->h_extensions,
+ bdc->no_policy_details ? NULL : &bdc->h_policy,
bdc->exchange_timestamp,
bdc->wire_deadline,
bdc->refund_deadline,
@@ -242,7 +243,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;
@@ -474,7 +475,7 @@ parse_coin (struct MHD_Connection *connection,
&dc->h_wire,
&dc->h_contract_terms,
&deposit->coin.h_age_commitment,
- &dc->h_extensions,
+ dc->no_policy_details ? NULL : &dc->h_policy,
&deposit->coin.denom_pub_hash,
dc->timestamp,
&dc->merchant_pub,
@@ -500,7 +501,7 @@ parse_coin (struct MHD_Connection *connection,
but rather insert them ONCE and then per-coin only use
the resulting extension UUID/serial; so the data structure
here should be changed once we look at extensions in earnest. */
- deposit->extension_details = dc->extension_details;
+ deposit->policy_details = dc->policy_details;
deposit->timestamp = dc->timestamp;
deposit->refund_deadline = dc->refund_deadline;
deposit->wire_deadline = dc->wire_deadline;
@@ -517,7 +518,6 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
struct BatchDepositContext dc;
json_t *coins;
bool no_refund_deadline = true;
- bool no_extensions = true;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("merchant_payto_uri",
&dc.payto_uri),
@@ -530,9 +530,9 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
GNUNET_JSON_spec_json ("coins",
&coins),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_json ("extension_details",
- &dc.extension_details),
- &no_extensions),
+ GNUNET_JSON_spec_json ("policy",
+ &dc.policy_details),
+ &dc.no_policy_details),
GNUNET_JSON_spec_timestamp ("timestamp",
&dc.timestamp),
GNUNET_JSON_spec_mark_optional (
@@ -607,11 +607,11 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
TALER_merchant_wire_signature_hash (dc.payto_uri,
&dc.wire_salt,
&dc.h_wire);
- /* FIXME-OEC: #7270 hash actual extension JSON object here */
- // if (! no_extensions)
- memset (&dc.h_extensions,
- 0,
- sizeof (dc.h_extensions));
+ if (! dc.no_policy_details)
+ {
+ TALER_deposit_policy_hash (dc.policy_details,
+ &dc.h_policy);
+ }
dc.num_coins = json_array_size (coins);
if (0 == dc.num_coins)
{
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index 0484ab07..033245f5 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -47,7 +47,7 @@
* @param connection connection to the client
* @param coin_pub public key of the coin
* @param h_wire hash of wire details
- * @param h_extensions hash of applicable extensions
+ * @param h_policy hash of applicable extensions
* @param h_contract_terms hash of contract details
* @param exchange_timestamp exchange's timestamp
* @param refund_deadline until when this deposit be refunded
@@ -61,7 +61,7 @@ reply_deposit_success (
struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_ExtensionContractHashP *h_extensions,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_PrivateContractHashP *h_contract_terms,
struct GNUNET_TIME_Timestamp exchange_timestamp,
struct GNUNET_TIME_Timestamp refund_deadline,
@@ -78,7 +78,7 @@ reply_deposit_success (
&TEH_keys_exchange_sign_,
h_contract_terms,
h_wire,
- h_extensions,
+ h_policy,
exchange_timestamp,
wire_deadline,
refund_deadline,
@@ -115,6 +115,11 @@ struct DepositContext
const struct TALER_EXCHANGEDB_Deposit *deposit;
/**
+ * Extension handler for policy, maybe NULL.
+ */
+ const struct TALER_Extension *policy_extension;
+
+ /**
* Our timestamp (when we received the request).
* Possibly updated by the transaction if the
* request is idempotent (was repeated).
@@ -156,6 +161,7 @@ deposit_transaction (void *cls,
enum GNUNET_DB_QueryStatus qs;
bool balance_ok;
bool in_conflict;
+ bool blocked_by_policy = false;
qs = TEH_make_coin_known (&dc->deposit->coin,
connection,
@@ -163,11 +169,30 @@ deposit_transaction (void *cls,
mhd_ret);
if (qs < 0)
return qs;
+
+ /* Check and apply policies, if applicable */
+ if (NULL != dc->policy_extension)
+ {
+ const struct TALER_Extension *ext = dc->policy_extension;
+ struct TALER_ExtensionsPolicySerialID serialID;
+ struct GNUNET_TIME_Timestamp deadline;
+ GNUNET_assert (ext->parse_policy_details);
+
+ qs = ext->parse_policy_details (dc->deposit->policy_details,
+ &serialID,
+ &deadline);
+
+ if (qs < 0)
+ return qs;
+
+ blocked_by_policy = true;
+ }
+
qs = TEH_plugin->do_deposit (TEH_plugin->cls,
dc->deposit,
dc->known_coin_id,
&dc->h_payto,
- false, /* FIXME-OEC: extension blocked #7270 */
+ blocked_by_policy,
&dc->exchange_timestamp,
&balance_ok,
&in_conflict);
@@ -216,6 +241,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
struct DepositContext dc;
struct TALER_EXCHANGEDB_Deposit deposit;
const char *payto_uri;
+ struct TALER_ExtensionPolicyHashP *ph_policy = NULL;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("merchant_payto_uri",
&payto_uri),
@@ -228,8 +254,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.coin.denom_pub_hash),
TALER_JSON_spec_denom_sig ("ub_sig",
&deposit.coin.denom_sig),
- GNUNET_JSON_spec_fixed_auto ("merchant_pub",
- &deposit.merchant_pub),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&deposit.h_contract_terms),
GNUNET_JSON_spec_mark_optional (
@@ -240,12 +264,21 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.csig),
GNUNET_JSON_spec_timestamp ("timestamp",
&deposit.timestamp),
+
+ /* TODO: refund_deadline and merchant_pub will move into the
+ * extension policy_merchant_refunds */
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_timestamp ("refund_deadline",
&deposit.refund_deadline),
NULL),
+ GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+ &deposit.merchant_pub),
GNUNET_JSON_spec_timestamp ("wire_transfer_deadline",
&deposit.wire_deadline),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_json ("policy",
+ &deposit.policy_details),
+ &deposit.no_policy_details),
GNUNET_JSON_spec_end ()
};
struct TALER_MerchantWireHashP h_wire;
@@ -383,6 +416,13 @@ TEH_handler_deposit (struct MHD_Connection *connection,
NULL);
}
+ if (! deposit.no_policy_details)
+ {
+ TALER_deposit_policy_hash (deposit.policy_details,
+ &deposit.h_policy);
+ ph_policy = &deposit.h_policy;
+ }
+
deposit.deposit_fee = dk->meta.fees.deposit;
/* check coin signature */
switch (dk->denom_pub.cipher)
@@ -426,7 +466,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&h_wire,
&deposit.h_contract_terms,
&deposit.coin.h_age_commitment,
- NULL /* FIXME: h_extensions! */,
+ ph_policy,
&deposit.coin.denom_pub_hash,
deposit.timestamp,
&deposit.merchant_pub,
@@ -481,7 +521,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
res = reply_deposit_success (connection,
&deposit.coin.coin_pub,
&h_wire,
- NULL /* FIXME: h_extensions! */,
+ ph_policy,
&deposit.h_contract_terms,
dc.exchange_timestamp,
deposit.refund_deadline,
diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c
index d6c26f6f..e8d3e4af 100644
--- a/src/exchange/taler-exchange-httpd_extensions.c
+++ b/src/exchange/taler-exchange-httpd_extensions.c
@@ -77,65 +77,84 @@ extension_update_event_cb (void *cls,
return;
}
- // Get the config from the database as string
+ // 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,
- extension->name,
- &config_str);
+ qs = TEH_plugin->get_extension_manifest (TEH_plugin->cls,
+ extension->name,
+ &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 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 (manifest_js);
return;
}
// Call the parser for the extension
- ret = extension->load_json_config (
+ ret = extension->load_config (
(struct TALER_Extension *) extension,
- 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",
- extension->name);
+ "Couldn't parse configuration for extension %s from the manifest in the database: %s\n",
+ extension->name,
+ manifest_str);
GNUNET_break (0);
}
+
+ free (manifest_str);
+ json_decref (manifest_js);
}
/* Special case age restriction: Update global flag and mask */
if (TALER_Extension_AgeRestriction == type)
{
- TEH_age_restriction_enabled =
- TALER_extensions_age_restriction_is_enabled ();
+ 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",
+ TEH_age_restriction_enabled ? "enabled": "DISABLED",
+ TALER_age_mask_to_string (&conf->mask));
+
}
}
@@ -143,14 +162,30 @@ extension_update_event_cb (void *cls,
enum GNUNET_GenericReturnValue
TEH_extensions_init ()
{
- GNUNET_assert (GNUNET_OK ==
- TALER_extension_age_restriction_register ());
-
/* Set the event handler for updates */
struct GNUNET_DB_EventHeaderP ev = {
.size = htons (sizeof (ev)),
.type = htons (TALER_DBEVENT_EXCHANGE_EXTENSIONS_UPDATED),
};
+
+ /* Load the shared libraries first */
+ if (GNUNET_OK !=
+ 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,
@@ -162,17 +197,24 @@ TEH_extensions_init ()
return GNUNET_SYSERR;
}
- /* FIXME #7270: shall we load the extensions from the config right away?
- * We do have to for now, as otherwise denominations with age restriction
- * will not have the age mask set right upon initial generation.
- */
- TALER_extensions_load_taler_config (TEH_cfg);
-
/* Trigger the initial load of configuration from the db */
- for (const struct TALER_Extension *it = TALER_extensions_get_head ();
- NULL != it->next;
+ for (const struct TALER_Extensions *it = TALER_extensions_get_head ();
+ NULL != it && NULL != it->extension;
it = it->next)
- extension_update_event_cb (NULL, &it->type, sizeof(it->type));
+ {
+ const struct TALER_Extension *ext = it->extension;
+ uint32_t typ = htonl (ext->type);
+ char *manifest = json_dumps (ext->manifest (ext), JSON_COMPACT);
+
+ TEH_plugin->set_extension_manifest (TEH_plugin->cls,
+ ext->name,
+ manifest);
+
+ extension_update_event_cb (NULL,
+ &typ,
+ sizeof(typ));
+ free (manifest);
+ }
return GNUNET_OK;
}
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index a6ad9976..aa5d6bd4 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -815,10 +815,7 @@ static struct TALER_AgeMask
load_age_mask (const char*section_name)
{
static const struct TALER_AgeMask null_mask = {0};
- struct TALER_AgeMask age_mask = TALER_extensions_age_restriction_ageMask ();
-
- if (age_mask.bits == 0)
- return null_mask;
+ enum GNUNET_GenericReturnValue ret;
if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value (
TEH_cfg,
@@ -826,22 +823,29 @@ load_age_mask (const char*section_name)
"AGE_RESTRICTED")))
return null_mask;
+ if (GNUNET_SYSERR ==
+ (ret = GNUNET_CONFIGURATION_get_value_yesno (TEH_cfg,
+ section_name,
+ "AGE_RESTRICTED")))
{
- enum GNUNET_GenericReturnValue ret;
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section_name,
+ "AGE_RESTRICTED",
+ "Value must be YES or NO\n");
+ return null_mask;
+ }
- if (GNUNET_SYSERR ==
- (ret = GNUNET_CONFIGURATION_get_value_yesno (TEH_cfg,
- section_name,
- "AGE_RESTRICTED")))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section_name,
- "AGE_RESTRICTED",
- "Value must be YES or NO\n");
- return null_mask;
- }
+ if (GNUNET_OK == ret)
+ {
+ 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);
+ return TEH_age_restriction_config.mask;
}
- return age_mask;
+
+
+ return null_mask;
}
@@ -1898,41 +1902,29 @@ create_krd (struct TEH_KeyStateHandle *ksh,
bool has_extensions = false;
/* Fill in the configurations of the enabled extensions */
- for (const struct TALER_Extension *extension = TALER_extensions_get_head ();
- NULL != extension;
- extension = extension->next)
+ for (const struct TALER_Extensions *iter = TALER_extensions_get_head ();
+ NULL != iter && NULL != iter->extension;
+ iter = iter->next)
{
- json_t *ext;
- json_t *config_json;
+ const struct TALER_Extension *extension = iter->extension;
+ json_t *manifest;
int r;
- /* skip if not configured == disabled */
- if (NULL == extension->config ||
- NULL == extension->config_json)
+ /* skip if not enabled */
+ if (! extension->enabled)
continue;
/* flag our findings so far */
has_extensions = true;
- GNUNET_assert (NULL != extension->config_json);
-
- config_json = json_copy (extension->config_json);
- GNUNET_assert (NULL != config_json);
- ext = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_bool ("critical",
- extension->critical),
- GNUNET_JSON_pack_string ("version",
- extension->version),
- GNUNET_JSON_pack_object_steal ("config",
- config_json)
- );
- GNUNET_assert (NULL != ext);
+ manifest = extension->manifest (extension);
+ GNUNET_assert (manifest);
r = json_object_set_new (
extensions,
extension->name,
- ext);
+ manifest);
GNUNET_assert (0 == r);
}
@@ -1948,12 +1940,16 @@ create_krd (struct TEH_KeyStateHandle *ksh,
extensions);
GNUNET_assert (0 == r);
- sig = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("extensions_sig",
- &TEH_extensions_sig));
+ /* Add the signature of the extensions, if it is not zero */
+ if (TEH_extensions_signed)
+ {
+ sig = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_data_auto ("extensions_sig",
+ &TEH_extensions_sig));
- r = json_object_update (keys, sig);
- GNUNET_assert (0 == r);
+ r = json_object_update (keys, sig);
+ GNUNET_assert (0 == r);
+ }
}
else
{
@@ -2560,6 +2556,7 @@ build_key_state (struct HelperState *hs,
true);
return NULL;
}
+
/* NOTE: ONLY fetches non-revoked AND master-signed signkeys! */
qs = TEH_plugin->iterate_active_signkeys (TEH_plugin->cls,
&signkey_info_cb,
diff --git a/src/exchange/taler-exchange-httpd_management_extensions.c b/src/exchange/taler-exchange-httpd_management_extensions.c
index a663b1b0..ad2057a9 100644
--- a/src/exchange/taler-exchange-httpd_management_extensions.c
+++ b/src/exchange/taler-exchange-httpd_management_extensions.c
@@ -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,10 +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 (manifest);
if (qs < 0)
{
@@ -137,6 +137,7 @@ set_extensions (void *cls,
/* All extensions configured, update the signature */
TEH_extensions_sig = sec->extensions_sig;
+ TEH_extensions_signed = true;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; /* only 'success', so >=0, matters here */
}
@@ -150,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));
@@ -159,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;
@@ -175,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;
@@ -223,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 (
@@ -235,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))
{
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index a25d6ff4..85090ced 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -623,8 +623,7 @@ resolve_refreshes_reveal_denominations (
bool failed = true;
/* Has been checked in handle_refreshes_reveal_json() */
- GNUNET_assert (ng ==
- TALER_extensions_age_restriction_num_groups ());
+ GNUNET_assert (ng == TEH_age_restriction_config.num_groups);
rctx->old_age_commitment = GNUNET_new (struct TALER_AgeCommitment);
oac = rctx->old_age_commitment;
@@ -931,7 +930,7 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection,
/* Sanity check of age commitment: If it was provided, it _must_ be an array
* of the size the # of age groups */
if (NULL != old_age_commitment_json
- && TALER_extensions_age_restriction_num_groups () !=
+ && TEH_age_restriction_config.num_groups !=
json_array_size (old_age_commitment_json))
{
GNUNET_break_op (0);
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 516b3646..fb6bc21d 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -76,7 +76,7 @@ TEH_RESPONSE_compile_transaction_history (
&h_wire,
&deposit->h_contract_terms,
&deposit->h_age_commitment,
- NULL /* h_extensions! */,
+ &deposit->h_policy,
&deposit->h_denom_pub,
deposit->timestamp,
&deposit->merchant_pub,