From 2b8b92486ac28aff4a7d99fc18084db3d6f9617c Mon Sep 17 00:00:00 2001 From: Matej Habrnal Date: Fri, 12 Feb 2016 14:20:19 +0100 Subject: [PATCH] lib: introduce global configuration + option for excluded elements Related to rhbz#1168494 Signed-off-by: Matej Habrnal Signed-off-by: Jakub Filak --- src/include/Makefile.am | 2 +- src/include/global_configuration.h | 45 ++++++++++++ src/include/internal_libreport.h | 2 +- src/include/libreport_types.h | 2 + src/lib/Makefile.am | 3 +- src/lib/global_configuration.c | 143 +++++++++++++++++++++++++++++++++++++ src/plugins/reporter-upload.c | 4 +- 7 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 src/include/global_configuration.h create mode 100644 src/lib/global_configuration.c diff --git a/src/include/Makefile.am b/src/include/Makefile.am index de44cda..062bffb 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -9,7 +9,7 @@ libreport_include_HEADERS = \ run_event.h \ libreport_curl.h \ workflow.h \ - \ + global_configuration.h \ config_item_info.h \ file_obj.h \ internal_libreport.h \ diff --git a/src/include/global_configuration.h b/src/include/global_configuration.h new file mode 100644 index 0000000..9666796 --- /dev/null +++ b/src/include/global_configuration.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2015 ABRT team + Copyright (C) 2015 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef LIBREPORT_GLOBAL_CONFIGURATION_H +#define LIBREPORT_GLOBAL_CONFIGURATION_H + +#include "libreport_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define load_global_configuration libreport_load_global_configuration +bool load_global_configuration(void); + +#define load_global_configuration_from_dirs libreport_load_global_configuration_from_dirs +bool load_global_configuration_from_dirs(const char *dirs[], int dir_flags[]); + +#define free_global_configuration libreport_free_global_configuration +void free_global_configuration(void); + +#define get_global_always_excluded_elements libreport_get_global_always_excluded_elements +string_vector_ptr_t get_global_always_excluded_elements(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBREPORT_GLOBAL_CONFIGURATION_H */ diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h index 2046e69..b632803 100644 --- a/src/include/internal_libreport.h +++ b/src/include/internal_libreport.h @@ -45,7 +45,6 @@ #include #include #include -#include /* Try to pull in PATH_MAX */ #include #include @@ -91,6 +90,7 @@ int vdprintf(int d, const char *format, va_list ap); /* Pull in entire public libreport API */ #include "dump_dir.h" +#include "global_configuration.h" #include "event_config.h" #include "problem_data.h" #include "report.h" diff --git a/src/include/libreport_types.h b/src/include/libreport_types.h index 2c60972..eb70fca 100644 --- a/src/include/libreport_types.h +++ b/src/include/libreport_types.h @@ -19,9 +19,11 @@ #ifndef LIBREPORT_TYPES_H_ #define LIBREPORT_TYPES_H_ +#include #include typedef gchar **string_vector_ptr_t; +typedef const gchar *const *const_string_vector_const_ptr_t; #define string_vector_new_from_string libreport_string_vector_new_from_string string_vector_ptr_t string_vector_new_from_string(const char *vector); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 7d9722a..f9ea602 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -55,7 +55,8 @@ libreport_la_SOURCES = \ workflow_xml_parser.c \ config_item_info.c \ xml_parser.c \ - libreport_init.c + libreport_init.c \ + global_configuration.c libreport_la_CPPFLAGS = \ -I$(srcdir)/../include \ diff --git a/src/lib/global_configuration.c b/src/lib/global_configuration.c new file mode 100644 index 0000000..903a2fb --- /dev/null +++ b/src/lib/global_configuration.c @@ -0,0 +1,143 @@ +/* + Copyright (C) 2015 ABRT team + Copyright (C) 2015 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "global_configuration.h" +#include "internal_libreport.h" + +#define OPT_NAME_SCRUBBED_VARIABLES "ScrubbedENVVariables" +#define OPT_NAME_EXCLUDED_ELEMENTS "AlwaysExcludedElements" + +static const char *const s_recognized_options[] = { + OPT_NAME_SCRUBBED_VARIABLES, + OPT_NAME_EXCLUDED_ELEMENTS, + NULL, +}; + +static map_string_t *s_global_settings; + +bool load_global_configuration(void) +{ + static const char *dirs[] = { + CONF_DIR, + NULL, + NULL, + }; + + static int dir_flags[] = { +#if 0 + CONF_DIR_FLAG_NONE, +#else + /* jfilak: RHEL-7 do not use global configuration file */ + CONF_DIR_FLAG_OPTIONAL, +#endif + CONF_DIR_FLAG_OPTIONAL, + -1, + }; + + if (dirs[1] == NULL) + dirs[1] = get_user_conf_base_dir(); + + return load_global_configuration_from_dirs(dirs, dir_flags); +} + +bool load_global_configuration_from_dirs(const char *dirs[], int dir_flags[]) +{ + if (s_global_settings == NULL) + { + s_global_settings = new_map_string(); + + bool ret = load_conf_file_from_dirs_ext("libreport.conf", dirs, dir_flags, s_global_settings, + /*don't skip without value*/ false); + if (!ret) + { + error_msg("Failed to load libreport global configuration"); + free_global_configuration(); + return false; + } + + map_string_iter_t iter; + init_map_string_iter(&iter, s_global_settings); + const char *key, *value; + while(next_map_string_iter(&iter, &key, &value)) + { + /* Die to avoid security leaks in case where someone made a typo in a option name */ + if (!is_in_string_list(key, s_recognized_options)) + { + error_msg("libreport global configuration contains unrecognized option : '%s'", key); + free_global_configuration(); + return false; + } + } + } + else + log_notice("libreport global configuration already loaded"); + + return true; +} + +void free_global_configuration(void) +{ + if (s_global_settings != NULL) + { + free_map_string(s_global_settings); + s_global_settings = NULL; + } +} + +static void assert_global_configuration_initialized(void) +{ + if (NULL == s_global_settings) + { + error_msg("libreport global configuration is not initialized"); + abort(); + } +} + +#define get_helper(type, getter, name) \ + ({ \ + assert_global_configuration_initialized(); \ + type opt; \ + if (getter(s_global_settings, name, &opt)) \ + /* Die to avoid security leaks in case where someone made a error */ \ + error_msg_and_die("libreport global settings contains invalid data: '"name"'"); \ + opt;\ + }) + +string_vector_ptr_t get_global_always_excluded_elements(void) +{ + assert_global_configuration_initialized(); + + char *env_exclude = getenv("EXCLUDE_FROM_REPORT"); + const char *gc_exclude = get_map_string_item_or_NULL(s_global_settings, OPT_NAME_EXCLUDED_ELEMENTS); + + if (env_exclude != NULL && gc_exclude == NULL) + return string_vector_new_from_string(env_exclude); + + if (env_exclude == NULL && gc_exclude != NULL) + return string_vector_new_from_string(gc_exclude); + + if (env_exclude == NULL && gc_exclude == NULL) + return string_vector_new_from_string(NULL); + + char *joined_exclude = xasprintf("%s, %s", env_exclude, gc_exclude); + string_vector_ptr_t ret = string_vector_new_from_string(joined_exclude); + free(joined_exclude); + + return ret; +} diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c index 84c827b..6d83d2f 100644 --- a/src/plugins/reporter-upload.c +++ b/src/plugins/reporter-upload.c @@ -96,12 +96,12 @@ static int create_and_upload_archive( /* Write data to the tarball */ { - char *exclude_from_report = getenv("EXCLUDE_FROM_REPORT"); + string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements(); dd_init_next_file(dd); char *short_name, *full_name; while (dd_get_next_file(dd, &short_name, &full_name)) { - if (exclude_from_report && is_in_comma_separated_list(short_name, exclude_from_report)) + if (exclude_from_report && is_in_string_list(short_name, (const_string_vector_const_ptr_t)exclude_from_report)) goto next; // dd_get_next_file guarantees that it's a REG: -- 1.8.3.1