diff options
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/taler-exchange-httpd.c | 61 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd.h | 9 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_extensions.c | 59 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 74 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_management_extensions.c | 3 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refreshes_reveal.c | 9 |
6 files changed, 148 insertions, 67 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 496d3d29..d7651d79 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -98,6 +98,13 @@ 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. + */ +struct TALER_AgeRestrictionConfig TEH_age_restriction_config = {0}; + +/** * Handle to the HTTP server. */ static struct MHD_Daemon *mhd; @@ -139,11 +146,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 +172,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 +1042,46 @@ handle_post_auditors (struct TEH_RequestContext *rc, /** + * 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 MHD_HTTP_NOT_IMPLEMENTED; + + return ext->http_post_handler ( + rc->connection, + root, + &args[1]); +} + + +/** * Handle incoming HTTP request. * * @param cls closure for MHD daemon (unused) @@ -1255,6 +1298,14 @@ handle_mhd_request (void *cls, .nargs = 4, .nargs_is_upper_bound = true }, + /* extensions endpoints */ + { + .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..77aab249 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,7 @@ struct TEH_RequestHandler }; +/* Age restriction configuration */ +extern struct TALER_AgeRestrictionConfig TEH_age_restriction_config; + #endif diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c index d6c26f6f..2a99d7a2 100644 --- a/src/exchange/taler-exchange-httpd_extensions.c +++ b/src/exchange/taler-exchange-httpd_extensions.c @@ -100,6 +100,9 @@ extension_update_event_cb (void *cls, // No config found -> disable extension if (NULL == config_str) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No configuration found for extension %s, disabling it\n", + extension->name); extension->disable ((struct TALER_Extension *) extension); return; } @@ -114,28 +117,40 @@ extension_update_event_cb (void *cls, err.text, err.source); GNUNET_break (0); + free(config_str); return; } // Call the parser for the extension ret = extension->load_json_config ( (struct TALER_Extension *) extension, - config); + json_object_get(config, "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 database: %s\n", + extension->name, + config_str); GNUNET_break (0); } + + free(config_str); + json_decref(config); } /* 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 (); + if (NULL != conf) + TEH_age_restriction_config = *conf; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "[age restriction] DB event has changed the config to %s with mask: %s\n", + conf->enabled ? "enabled": "disabled", + TALER_age_mask_to_string (&conf->mask)); + } } @@ -143,14 +158,21 @@ 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_load (TEH_cfg)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "failed to load extensions"); + return GNUNET_SYSERR; + } + extensions_eh = TEH_plugin->event_listen (TEH_plugin->cls, GNUNET_TIME_UNIT_FOREVER_REL, &ev, @@ -162,17 +184,20 @@ 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; + char *conf = json_dumps (ext->config_to_json (ext), JSON_COMPACT); + + TEH_plugin->set_extension_config (TEH_plugin->cls, + ext->name, + conf); + extension_update_event_cb (NULL, &ext->type, sizeof(ext->type)); + free (conf); + } return GNUNET_OK; } diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index a6ad9976..4fb8a717 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_config.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,34 +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) { + const struct TALER_Extension *extension = iter->extension; json_t *ext; - json_t *config_json; 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_JSON_pack_object_incref ("config", + extension->config_json) ); GNUNET_assert (NULL != ext); @@ -1948,12 +1947,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 +2563,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..c70ad25e 100644 --- a/src/exchange/taler-exchange-httpd_management_extensions.c +++ b/src/exchange/taler-exchange-httpd_management_extensions.c @@ -108,6 +108,8 @@ set_extensions (void *cls, taler_ext->name, config); + free (config); + if (qs < 0) { if (GNUNET_DB_STATUS_SOFT_ERROR == qs) @@ -137,6 +139,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 */ } diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index a25d6ff4..09ab572b 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -603,7 +603,7 @@ resolve_refreshes_reveal_denominations ( &rrc->coin_envelope_hash); } - if (TEH_age_restriction_enabled && + if (TEH_age_restriction_config.enabled && ((NULL == old_age_commitment_json) != TALER_AgeCommitmentHash_isNullOrZero ( &rctx->melt.session.coin.h_age_commitment))) @@ -614,7 +614,7 @@ resolve_refreshes_reveal_denominations ( /* Reconstruct the old age commitment and verify its hash matches the one * from the melt request */ - if (TEH_age_restriction_enabled && + if (TEH_age_restriction_config.enabled && (NULL != old_age_commitment_json)) { enum GNUNET_GenericReturnValue res; @@ -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); |