System.get API - Return system details (PHP+MySQL version, ad nauseum)
authorTim Otten <totten@civicrm.org>
Fri, 10 Apr 2015 03:54:52 +0000 (20:54 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 14 Jul 2015 04:00:05 +0000 (21:00 -0700)
Includes:
 * Civi+PHP+MySQL versions
 * Active components/extensions/modules
 * Redacted PHP INI settings

CRM/Core/Module.php
api/v3/System.php
api/v3/System/ini-whitelist.txt [new file with mode: 0644]

index 7bf9c2af5b65784ba4b0dee94de93a3d267b901a..fabe87917ea8369184e71be07d7c7190ee88bca3 100644 (file)
@@ -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;
+  }
+
 }
index b60d2d44a14a5dd760ac58cdd1916d1ce5d117d4..09affcba060ef3944ef4106ac6ca4320a5116c2c 100644 (file)
@@ -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 (file)
index 0000000..ab674b9
--- /dev/null
@@ -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