/lib/Watchdog.php
https://github.com/Alex8452/Kurogo-Mobile-Web-Doc-Translation · PHP · 148 lines · 99 code · 26 blank · 23 comment · 23 complexity · fb285aa17cb8b82dca6a940510cd3598 MD5 · raw file
- <?php
- class Watchdog {
- private static $_instance = NULL;
- protected $workingRealpath = false;
- protected $kurogoPathDirs = array();
- protected $safePathDirs = array();
- protected $safePathREs = array();
- private function __clone() {}
- protected function __construct() {
- // realpath returns true if the directory exists even if the file doesn't on PHP < 5.3
- $this->workingRealpath = version_compare(PHP_VERSION, '5.3.0') >= 0;
- }
- //
- // Internal implementation of functions to generate lists and
- // regular expressions describing acceptable file paths
- //
- protected function _getKurogoPathDirs() {
- if (!$this->kurogoPathDirs) {
- $rootDir = realpath(ROOT_DIR).DIRECTORY_SEPARATOR;
-
- if (!defined('SITE_DIR')) {
- return array($rootDir); // SiteConfig has not initialized yet
- }
-
- $this->kurogoPathDirs = array($rootDir);
-
- $siteDir = realpath(SITE_DIR).DIRECTORY_SEPARATOR;
- if (strncmp($siteDir, $rootDir, strlen($rootDir)) != 0) {
- $this->kurogoPathDirs[] = $siteDir;
- }
-
- // support for future feature to allow cache to be moved to a fast disk
- $cacheDir = realpath(CACHE_DIR).DIRECTORY_SEPARATOR;
- if (strncmp($cacheDir, $rootDir, strlen($rootDir)) != 0) {
- $this->kurogoPathDirs[] = $cacheDir;
- }
- //error_log('Kurogo files: '.print_r($this->kurogoPathDirs, true));
- }
-
- return $this->kurogoPathDirs;
- }
- protected function _getSafePathDirs() {
- if (!$this->safePathDirs && defined('SITE_DIR')) {
- $this->safePathDirs = array(
- realpath(SITE_DIR).DIRECTORY_SEPARATOR.'media'.DIRECTORY_SEPARATOR,
- realpath(CACHE_DIR).DIRECTORY_SEPARATOR.'FileLoader'.DIRECTORY_SEPARATOR,
- );
- //error_log('Safe files: '.print_r($this->safePathDirs, true));
- }
-
- return $this->safePathDirs;
- }
- protected function _getSafePathREs() {
- if (!$this->safePathREs && defined('SITE_DIR') && defined('THEME_DIR')) {
- $delimiter = ';';
- $this->safePathREs = array(
- $delimiter.
- '^('.preg_quote(realpath(THEME_DIR), $delimiter).'|'.
- preg_quote(realpath(SITE_DIR).DIRECTORY_SEPARATOR, $delimiter).'app|'.
- preg_quote(realpath(ROOT_DIR).DIRECTORY_SEPARATOR, $delimiter).'app)'.
- preg_quote(DIRECTORY_SEPARATOR, $delimiter).
- '(common|modules'.preg_quote(DIRECTORY_SEPARATOR, $delimiter).'[^'.preg_quote(DIRECTORY_SEPARATOR, $delimiter).']+)'.
- preg_quote(DIRECTORY_SEPARATOR, $delimiter).
- '(css|images|javascript)'.
- preg_quote(DIRECTORY_SEPARATOR, $delimiter).
- $delimiter,
- );
- //error_log('Safe REs: '.print_r($this->safePathREs, true));
- }
-
- return $this->safePathREs;
- }
- //
- // Internal implementation of path checking functions
- //
- protected function _safePath($path) {
- // realpath_exists calls Watchdog::kurogoPath()
- $test = realpath($path);
- if ($test && ($this->workingRealpath || file_exists($test))) {
- // Check safe directories first because strncmp is fast
- foreach ($this->_getSafePathDirs() as $dir) {
- if (strncmp($test, $dir, strlen($dir)) == 0) {
- return $test;
- }
- }
-
- foreach ($this->_getSafePathREs() as $re) {
- if (preg_match($re, $test)) {
- return $test;
- }
- }
- error_log("WARNING! Blocking attempt from ".$_SERVER['REMOTE_ADDR']." to access unsafe path '$test'");
- }
-
- // path is invalid or refers to an unsafe file
- return false;
- }
- protected function _kurogoPath($path) {
- // realpath_exists calls Watchdog::kurogoPath()
- $test = realpath($path);
- if ($test && ($this->workingRealpath || file_exists($test))) {
- foreach ($this->_getKurogoPathDirs() as $dir) {
- if (strncmp($test, $dir, strlen($dir)) == 0) {
- return $test;
- }
- }
- error_log("WARNING! Blocking attempt from ".$_SERVER['REMOTE_ADDR']." to access non-Kurogo path '$test'");
- }
-
- // path is invalid or outside Kurogo directories
- return false;
- }
- //
- // Shared instance of Watchdog class
- //
- protected static function sharedInstance() {
- if (!isset(self::$_instance)) {
- $c = __CLASS__;
- self::$_instance = new $c;
- }
- return self::$_instance;
- }
- //
- // Public static helper functions
- //
- public static function safePath($path) {
- return self::sharedInstance()->_safePath($path);
- }
- public static function kurogoPath($path) {
- return self::sharedInstance()->_kurogoPath($path);
- }
- }