From 5bbcc82374632713a022a8cc7981e5cc0bdfd0dd Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 9 Apr 2015 20:54:52 -0700 Subject: [PATCH] System.get API - Return system details (PHP+MySQL version, ad nauseum) Includes: * Civi+PHP+MySQL versions * Active components/extensions/modules * Redacted PHP INI settings --- CRM/Core/Module.php | 19 +++ api/v3/System.php | 77 +++++++++- api/v3/System/ini-whitelist.txt | 256 ++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+), 2 deletions(-) create mode 100644 api/v3/System/ini-whitelist.txt diff --git a/CRM/Core/Module.php b/CRM/Core/Module.php index 7bf9c2af5b..fabe87917e 100644 --- a/CRM/Core/Module.php +++ b/CRM/Core/Module.php @@ -71,4 +71,23 @@ class CRM_Core_Module { return $result; } + /** + * Get the status for each module. + * + * @param array $modules + * Array(CRM_Core_Module). + * @return array + * Array(string $moduleName => string $statusCode). + * @see CRM_Extension_Manager::STATUS_INSTALLED + * @see CRM_Extension_Manager::STATUS_DISABLED + */ + public static function collectStatuses($modules) { + $statuses = array(); + foreach ($modules as $module) { + $statuses[$module->name] = $module->is_active ? CRM_Extension_Manager::STATUS_INSTALLED : CRM_Extension_Manager::STATUS_DISABLED; + + } + return $statuses; + } + } diff --git a/api/v3/System.php b/api/v3/System.php index b60d2d44a1..09affcba06 100644 --- a/api/v3/System.php +++ b/api/v3/System.php @@ -175,11 +175,84 @@ function _civicrm_api3_system_log_spec(&$params) { * @return array */ function civicrm_api3_system_get($params) { + $config = CRM_Core_Config::singleton(); $returnValues = array( array( - 'version' => CRM_Utils_System::version(), - 'uf' => CIVICRM_UF, + 'version' => CRM_Utils_System::version(), // deprecated in favor of civi.version + 'uf' => CIVICRM_UF, // deprecated in favor of cms.type + 'php' => array( + 'version' => phpversion(), + 'tz' => date_default_timezone_get(), + 'extensions' => get_loaded_extensions(), + 'ini' => _civicrm_api3_system_get_redacted_ini(), + ), + 'mysql' => array( + 'version' => CRM_Core_DAO::singleValueQuery('SELECT @@version'), + ), + 'cms' => array( + 'type' => CIVICRM_UF, + 'modules' => CRM_Core_Module::collectStatuses($config->userSystem->getModules()), + ), + 'civi' => array( + 'version' => CRM_Utils_System::version(), + 'dev' => (bool) CRM_Utils_System::isDevelopment(), + 'components' => array_keys(CRM_Core_Component::getEnabledComponents()), + 'extensions' => preg_grep( + '/^uninstalled$/', + CRM_Extension_System::singleton()->getManager()->getStatuses(), + PREG_GREP_INVERT + ), + 'exampleUrl' => CRM_Utils_System::url('civicrm/example', NULL, TRUE, NULL, FALSE), + ), ), ); + return civicrm_api3_create_success($returnValues, $params, 'System', 'get'); } + +/** + * Generate a sanitized/anonymized/redacted dump of the PHP configuration. + * + * Some INI fields contain site-identifying information (SII) -- e.g. URLs, + * hostnames, file paths, IP addresses, passwords, or free-form comments + * could be used to identify a site or gain access to its resources. + * + * A number of INI fields have been examined to determine whether they + * contain SII. Approved fields are put in a whitelist; all other fields + * are redacted. + * + * Redaction hides the substance of a field but does not completely omit + * all information. Consider the field 'mail.log' - setting this field + * has a functional effect (it enables or disables the logging behavior) + * and also points to particular file. Empty values (FALSE/NULL/0/"") + * will pass through redaction, but all other values will be replaced + * by a string (eg "REDACTED"). This roughly indicates whether the + * option is enabled/disabled without giving away its content. + * + * @return array + */ +function _civicrm_api3_system_get_redacted_ini() { + static $whitelist = NULL; + if ($whitelist === NULL) { + $whitelistFile = __DIR__ . '/System/ini-whitelist.txt'; + $whitelist = array_filter( + explode("\n", file_get_contents($whitelistFile)), + function ($k) { + return !empty($k) && !preg_match('/^\s*#/', $k); + } + ); + } + + $inis = ini_get_all(NULL, FALSE); + $result = array(); + foreach ($inis as $k => $v) { + if (empty($v) || in_array($k, $whitelist)) { + $result[$k] = $v; + } + else { + $result[$k] = 'REDACTED'; + } + } + + return $result; +} diff --git a/api/v3/System/ini-whitelist.txt b/api/v3/System/ini-whitelist.txt new file mode 100644 index 0000000000..ab674b93fd --- /dev/null +++ b/api/v3/System/ini-whitelist.txt @@ -0,0 +1,256 @@ +## This file contains a list of INI fields that may +## be returned by the System.get API. +# Omit: SMTP +allow_call_time_pass_reference +allow_url_fopen +allow_url_include +always_populate_raw_post_data +apc.cache_by_default +apc.canonicalize +apc.coredump_unmap +apc.enable_cli +apc.enabled +apc.file_md5 +apc.file_update_protection +# Omit: apc.filters +apc.gc_ttl +apc.include_once_override +apc.lazy_classes +apc.lazy_functions +apc.max_file_size +# Omit: apc.mmap_file_mask +apc.num_files_hint +# Omit: apc.preload_path +apc.report_autofilter +apc.rfc1867 +apc.rfc1867_freq +# Omit: apc.rfc1867_name +# Omit: apc.rfc1867_prefix +apc.rfc1867_ttl +apc.serializer +apc.shm_segments +apc.shm_size +apc.slam_defense +apc.stat +apc.stat_ctime +apc.ttl +apc.use_request_time +apc.user_entries_hint +apc.user_ttl +apc.write_lock +arg_separator.input +arg_separator.output +asp_tags +assert.active +assert.bail +# Omit: assert.callback +assert.quiet_eval +assert.warning +# Omit: auto_append_file +auto_detect_line_endings +auto_globals_jit +# Omit: auto_prepend_file +bcmath.scale +# Omit: browscap +# Omit: curl.cainfo +date.default_latitude +date.default_longitude +date.sunrise_zenith +date.sunset_zenith +date.timezone +# Omit: dba.default_handler +default_charset +default_mimetype +default_socket_timeout +define_syslog_variables +disable_classes +disable_functions +display_errors +display_startup_errors +# Omit: doc_root +# Omit: docref_ext +# Omit: docref_root +enable_dl +enable_post_data_reading +# Omit: error_append_string +# Omit: error_log +# Omit: error_prepend_string +error_reporting +exif.decode_jis_intel +exif.decode_jis_motorola +exif.decode_unicode_intel +exif.decode_unicode_motorola +exif.encode_jis +exif.encode_unicode +exit_on_timeout +expose_php +# Omit: extension_dir +file_uploads +filter.default +filter.default_flags +# Omit: from +gd.jpeg_ignore_warning +highlight.bg +highlight.comment +highlight.default +highlight.html +highlight.keyword +highlight.string +html_errors +iconv.input_encoding +iconv.internal_encoding +iconv.output_encoding +ignore_repeated_errors +ignore_repeated_source +ignore_user_abort +implicit_flush +# Omit: include_path +intl.default_locale +intl.error_level +ldap.max_links +log_errors +log_errors_max_len +magic_quotes_gpc +magic_quotes_runtime +magic_quotes_sybase +mail.add_x_header +# Omit: mail.force_extra_parameters +# Omit: mail.log +max_execution_time +max_file_uploads +max_input_nesting_level +max_input_time +max_input_vars +mbstring.detect_order +mbstring.encoding_translation +mbstring.func_overload +mbstring.http_input +mbstring.http_output +mbstring.http_output_conv_mimetypes +mbstring.internal_encoding +mbstring.language +mbstring.strict_detection +mbstring.substitute_character +# Omit: mcrypt.algorithms_dir +# Omit: mcrypt.modes_dir +memory_limit +mysql.allow_local_infile +mysql.allow_persistent +mysql.connect_timeout +# Omit: mysql.default_host +# Omit: mysql.default_password +# Omit: mysql.default_port +# Omit: mysql.default_socket +# Omit: mysql.default_user +mysql.max_links +mysql.max_persistent +mysql.trace_mode +mysqli.allow_local_infile +mysqli.allow_persistent +# Omit: mysqli.default_host +# Omit: mysqli.default_port +# Omit: mysqli.default_pw +# Omit: mysqli.default_socket +# Omit: mysqli.default_user +mysqli.max_links +mysqli.max_persistent +mysqli.reconnect +# Omit: open_basedir +output_buffering +output_handler +pcre.backtrack_limit +pcre.recursion_limit +# Omit: pdo_mysql.default_socket +pgsql.allow_persistent +pgsql.auto_reset_persistent +pgsql.ignore_notice +pgsql.log_notice +pgsql.max_links +pgsql.max_persistent +# Omit: phar.cache_list +phar.readonly +phar.require_hash +post_max_size +precision +realpath_cache_size +realpath_cache_ttl +register_argc_argv +register_globals +register_long_arrays +report_memleaks +report_zend_debug +request_order +safe_mode +# Omit: safe_mode_allowed_env_vars +# Omit: safe_mode_exec_dir +safe_mode_gid +# Omit: safe_mode_include_dir +# Omit: safe_mode_protected_env_vars +# Omit: sendmail_from +# Omit: sendmail_path +serialize_precision +session.auto_start +session.bug_compat_42 +session.bug_compat_warn +session.cache_expire +# Omit: session.cache_limiter +# Omit: session.cookie_domain +session.cookie_httponly +session.cookie_lifetime +# Omit: session.cookie_path +session.cookie_secure +# Omit: session.entropy_file +# Omit: session.entropy_length +session.gc_divisor +session.gc_maxlifetime +session.gc_probability +# Omit: session.hash_bits_per_character +session.hash_function +# Omit: session.name +session.referer_check +# Omit: session.save_handler +# Omit: session.save_path +session.serialize_handler +session.upload_progress.cleanup +session.upload_progress.enabled +session.upload_progress.freq +session.upload_progress.min_freq +# Omit: session.upload_progress.name +# Omit: session.upload_progress.prefix +session.use_cookies +session.use_only_cookies +session.use_trans_sid +short_open_tag +# Omit: smtp_port +soap.wsdl_cache +# Omit: soap.wsdl_cache_dir +soap.wsdl_cache_enabled +soap.wsdl_cache_limit +soap.wsdl_cache_ttl +sql.safe_mode +# Omit: sqlite3.extension_dir +track_errors +# Omit: unserialize_callback_func +upload_max_filesize +# Omit: upload_tmp_dir +url_rewriter.tags +user_agent +# Omit: user_dir +user_ini.cache_ttl +# Omit: user_ini.filename +variables_order +xmlrpc_error_number +xmlrpc_errors +# Omit:'xsl.security_prefs +y2k_compliance +yaz.keepalive +# Omit: yaz.log_file +yaz.log_mask +yaz.max_links +zend.detect_unicode +zend.enable_gc +zend.multibyte +zend.script_encoding +zlib.output_compression +zlib.output_compression_level +# Omit: zlib.output_handler -- 2.25.1