diff options
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/taler-exchange-httpd.c | 112 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd.h | 10 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_batch-deposit.c | 34 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 56 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_extensions.c | 100 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 85 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_management_extensions.c | 36 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refreshes_reveal.c | 5 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_responses.c | 2 |
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, |