From f4bb05eae25364afcba2e4cd6c2ad5dfe4e36fe2 Mon Sep 17 00:00:00 2001 From: Hans Zandbelt Date: Wed, 20 Dec 2023 12:29:01 +0100 Subject: [PATCH] validate configured class names in OIDCMetricsData Signed-off-by: Hans Zandbelt --- src/config.c | 16 ++++++++++++---- src/metrics.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/metrics.h | 1 + 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/config.c b/src/config.c index 26498dd9..9e0ab66f 100644 --- a/src/config.c +++ b/src/config.c @@ -1132,10 +1132,18 @@ static const char *oidc_set_info_hook_data(cmd_parms *cmd, void *m, const char * static const char *oidc_set_metrics_hook_data(cmd_parms *cmd, void *m, const char *arg) { oidc_cfg *cfg = (oidc_cfg *)ap_get_module_config(cmd->server->module_config, &auth_openidc_module); - if (cfg->metrics_hook_data == NULL) - cfg->metrics_hook_data = apr_hash_make(cmd->pool); - apr_hash_set(cfg->metrics_hook_data, arg, APR_HASH_KEY_STRING, arg); - return NULL; + const char *rv = NULL; + char *valid_names = NULL; + if (oidc_metrics_is_valid_classname(cmd->pool, arg, &valid_names) == TRUE) { + if (cfg->metrics_hook_data == NULL) + cfg->metrics_hook_data = apr_hash_make(cmd->pool); + apr_hash_set(cfg->metrics_hook_data, arg, APR_HASH_KEY_STRING, arg); + } else { + rv = apr_psprintf(cmd->pool, "undefined metric class name: \"%s\", must be one of [%s]", arg, + valid_names); + } + return OIDC_CONFIG_DIR_RV(cmd, rv); + ; } static const char *oidc_set_trace_parent(cmd_parms *cmd, void *struct_ptr, const char *arg) { diff --git a/src/metrics.c b/src/metrics.c index a21963be..9ea22ad1 100644 --- a/src/metrics.c +++ b/src/metrics.c @@ -275,6 +275,46 @@ typedef struct oidc_metrics_timing_t { json_int_t count; } oidc_metrics_timing_t; +typedef struct oidc_metrics_add_classname_ctx_t { + apr_pool_t *pool; + char **valid_names; +} oidc_metrics_add_classname_ctx_t; + +static int _oidc_metrics_add_classnames(void *rec, const char *key, const char *value) { + oidc_metrics_add_classname_ctx_t *ctx = (oidc_metrics_add_classname_ctx_t *)rec; + *ctx->valid_names = apr_psprintf(ctx->pool, "%s%s%s", *ctx->valid_names ? *ctx->valid_names : "", + *ctx->valid_names ? " | " : "", value); + return 1; +} + +apr_byte_t oidc_metrics_is_valid_classname(apr_pool_t *pool, const char *name, char **valid_names) { + int i = 0; + int n = 0; + int rv = FALSE; + apr_table_t *names = apr_table_make(pool, 1); + oidc_metrics_add_classname_ctx_t ctx = {pool, valid_names}; + + n = sizeof(_oidc_metrics_timings_info) / sizeof(oidc_metrics_timing_info_t); + for (i = 0; i < n; i++) { + if (_oidc_strcmp(_oidc_metrics_timings_info[i].class_name, name) == 0) + rv = TRUE; + apr_table_set(names, _oidc_metrics_timings_info[i].class_name, + _oidc_metrics_timings_info[i].class_name); + } + n = sizeof(_oidc_metrics_counters_info) / sizeof(oidc_metrics_counter_info_t); + for (i = 0; i < n; i++) { + if (_oidc_strcmp(_oidc_metrics_counters_info[i].class_name, name) == 0) + rv = TRUE; + apr_table_set(names, _oidc_metrics_counters_info[i].class_name, + _oidc_metrics_counters_info[i].class_name); + } + + *valid_names = NULL; + apr_table_do(_oidc_metrics_add_classnames, &ctx, names, NULL); + + return rv; +} + /* * collection thread */ diff --git a/src/metrics.h b/src/metrics.h index f2b6ba10..be2da6e2 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -43,6 +43,7 @@ #ifndef MOD_AUTH_OPENIDC_METRICS_H_ #define MOD_AUTH_OPENIDC_METRICS_H_ +apr_byte_t oidc_metrics_is_valid_classname(apr_pool_t *pool, const char *name, char **valid_names); apr_byte_t oidc_metrics_cache_post_config(server_rec *s); apr_status_t oidc_metrics_cache_child_init(apr_pool_t *p, server_rec *s); apr_status_t oidc_metrics_cache_cleanup(server_rec *s);