diff --git a/config.ini b/config.ini index 8f4c019..127f608 100644 --- a/config.ini +++ b/config.ini @@ -22,7 +22,7 @@ cert_pub = NULL hash = NULL ;[subdirs] -;tftproot = tftpboot +;tftproot = data ;firmware = firmware ;settings = settings ;wallpapers = wallpapers diff --git a/lib/config.php b/lib/config.php index 194424e..40c9dff 100644 --- a/lib/config.php +++ b/lib/config.php @@ -1,4 +1,7 @@ replaceSubdirTreeStructure($config['subdirs']); $this->config = $config; } @@ -85,12 +88,12 @@ class ConfigParser { private function replaceSubdirTreeStructure($tmpSubdirs) { $tree_structure = Array( 'etc' => array('parent' => NULL, "strip" => true), - 'tftproot' => array('parent' => NULL, "strip" => true), - 'settings' => array('parent' => 'tftproot', "strip" => true), - 'wallpapers' => array('parent' => 'tftproot', "strip" => false), - 'ringtones' => array('parent' => 'tftproot', "strip" => true), - 'locales' => array('parent' => 'tftproot', "strip" => true), - 'firmware' => array('parent' => 'tftproot', "strip" => true), + 'data' => array('parent' => NULL, "strip" => true), + 'settings' => array('parent' => 'data', "strip" => true), + 'wallpapers' => array('parent' => 'data', "strip" => false), + 'ringtones' => array('parent' => 'data', "strip" => true), + 'locales' => array('parent' => 'data', "strip" => true), + 'firmware' => array('parent' => 'data', "strip" => true), 'languages' => array('parent' => 'locales', "strip" => false), 'countries' => array('parent' => 'locales', "strip" => false), ); @@ -98,16 +101,10 @@ class ConfigParser { $subdirs = Array(); foreach ($tree_structure as $key => $value) { if (!empty($tmpSubdirs[$key])) { - if (substr($tmpSubdirs[$key], 0, 1) !== "/") { - if (!$value['parent']) { - $path = $tmpSubdirs[$key]; - } else { - if (is_array($tmpSubdirs[$value['parent']])) { - $path = $tmpSubdirs[$value['parent']]['path'].'/'.$tmpSubdirs[$key]; - } else { - $path = $tmpSubdirs[$value['parent']].'/'.$tmpSubdirs[$key]; - } - } + if (!$value['parent']) { + $path = $tmpSubdirs[$key]; + } else { + $path = $subdirs[$value['parent']]['path'] . DIRECTORY_SEPARATOR . $tmpSubdirs[$key]; } $subdirs[$key] = array('path' => $path, 'strip' => $value['strip']); } @@ -190,7 +187,7 @@ $config = $configParser->getConfiguration(); switch($config['main']['log_type']) { case 'SYSLOG': - $logger = new Logger_Syslog($config['main']['log_level']); + $logger = new \SCCP\Logger\Logger_Syslog($config['main']['log_level']); break; case 'FILE': if (!isempty($config['main']['log_file'])) { diff --git a/lib/logger.php b/lib/logger.php index 249d121..2ad173b 100644 --- a/lib/logger.php +++ b/lib/logger.php @@ -1,4 +1,7 @@ _cache_file."' at Resolver::destruct"); }*/ if (!file_put_contents($this->_cache_file, serialize($this->_cache))) { - log_error_and_throw("Could not write to file '".$this->_cache_file."' at Resolver::destruct"); + Utils\log_error_and_throw("Could not write to file '".$this->_cache_file."' at Resolver::destruct"); } } } @@ -42,7 +45,7 @@ class fileCache extends resolveCache { public function addFile($filename, $realpath) { if ($this->check($filename)) - log_error("Duplicate file:$filename"); /* should we prevent this ? */ + Utils\log_error("Duplicate file:$filename"); /* should we prevent this ? */ $this->_cache[$filename] = $realpath; $this->_isDirty =true; } diff --git a/lib/resolver.php b/lib/resolver.php index e2f7673..2bdaef5 100644 --- a/lib/resolver.php +++ b/lib/resolver.php @@ -1,8 +1,14 @@ config = $config; - $this->cache = new fileCache($this->config['main']['cache_filename']); + $this->cache = new ResolveCache\fileCache($this->config['main']['cache_filename']); if ($this->cache->isDirty()) { $this->rebuildCache(); } } public function searchForFile($filename) { + $path = ""; foreach($this->config['subdirs'] as $key => $value) { - if ($key === "firmware" || $key === "tftproot" ) { + if ($key === "firmware" || $key === "data" || $key === "etc") { continue; } - $path = realpath($this->config['main']['base_path'] . "/" . $value['path'] . "/$filename"); - if (file_exists($path)) { - $this->cache->addFile($filename, $path); - return $path; + $path = realpath($this->config['main']['base_path'] . DIRECTORY_SEPARATOR . $value['path'] . DIRECTORY_SEPARATOR . $filename); + if (!$path) { + print("path: '" . $this->config['main']['base_path'] . DIRECTORY_SEPARATOR . $value['path'] . DIRECTORY_SEPARATOR . $filename . "' not found\n"); + return ResolveResult::FileNotFound; } + $this->cache->addFile($filename, $path); + return $path; } - log_error("File '$filename' does not exist"); + Utils\log_error("File '$filename' does not exist"); return ResolveResult::FileNotFound; } public function rebuildCache() { - log_debug("Rebuilding Cache, standby..."); + Utils\log_debug("Rebuilding Cache, standby..."); foreach($this->config['subdirs'] as $key =>$value) { - if ($key === "tftproot") { + if ($key === "data" || $key === "etc") { continue; } - $path = $this->config['main']['base_path'] . "/" . $value['path'] . "/"; - $dir_iterator = new RecursiveDirectoryIterator($path); - $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); + $path = realpath($this->config['main']['base_path'] . DIRECTORY_SEPARATOR . $value['path'] . DIRECTORY_SEPARATOR); + if (!$path) { + print("path: '" . $this->config['main']['base_path'] . DIRECTORY_SEPARATOR . $value['path'] . "' not found\n"); + break; + } + $dir_iterator = new \RecursiveDirectoryIterator($path); + $filter = new \RecursiveCallbackFilterIterator($dir_iterator, function ($current, $key, $iterator) { + // Skip hidden files and directories. + if ($current->getFilename()[0] === '.' || $current->getFilename() == "bak") { + return FALSE; + } + return TRUE; + }); + $iterator = new \RecursiveIteratorIterator($filter, \RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $file) { if ($file->isFile()) { if ($value['strip']) { $this->cache->addFile($file->getFileName(), $file->getPathname()); } else { $subdir = basename(dirname($file->getPathname())); - $this->cache->addFile('$subpath/'.$file->getFileName(), $file->getPathname()); + $this->cache->addFile($subdir. DIRECTORY_SEPARATOR . $file->getFileName(), $file->getPathname()); } } } @@ -89,14 +110,14 @@ class Resolver { log_error("Request is not a string"); return ResolveResult::RequestNotAString; } - log_debug($request . ":" . escapeshellarg($request) . ":" . utf8_urldecode($request) . "\n"); - $escaped_request = escapeshellarg(utf8_urldecode($request)); + Utils\log_debug($request . ":" . escapeshellarg($request) . ":" . Utils\utf8_urldecode($request) . "\n"); + $escaped_request = escapeshellarg(Utils\utf8_urldecode($request)); if ($escaped_request !== "'" . $request . "'") { log_error("Request '$request' contains invalid characters"); return ResolveResult::RequestContainsInvalidChar; } if (strstr($escaped_request, "..")) { - log_error("Request '$request' contains '..'"); + Utils\log_error("Request '$request' contains '..'"); return ResolveResult::RequestContainsPathWalk; } return ResolveResult::Ok; @@ -132,11 +153,11 @@ class Resolver { if(defined('STDIN') ) { $resolver = new Resolver($config); $test_cases = Array( - Array('request' => 'jar70sccp.9-4-2ES26.sbn', 'expected' => '/tftpboot/firmware/7970/jar70sccp.9-4-2ES26.sbn'), - Array('request' => 'Russian_Russian_Federation/be-sccp.jar', 'expected' => '/tftpboot/locales/languages/Russian_Russian_Federation/be-sccp.jar'), - Array('request' => 'Spain/g3-tones.xml', 'expected' => '/tftpboot/locales/countries/Spain/g3-tones.xml'), - Array('request' => '320x196x4/Chan-SCCP-b.png', 'expected' => '/tftpboot/wallpapers/320x196x4/Chan-SCCP-b.png'), - Array('request' => 'XMLDefault.cnf.xml', 'expected' => '/tftpboot/settings/XMLDefault.cnf.xml'), + Array('request' => 'jar70sccp.9-4-2ES26.sbn', 'expected' => '/data/firmware/7970/jar70sccp.9-4-2ES26.sbn'), + Array('request' => 'Russian_Russian_Federation/be-sccp.jar', 'expected' => '/data/locales/languages/Russian_Russian_Federation/be-sccp.jar'), + Array('request' => 'Spain/g3-tones.xml', 'expected' => '/data/locales/countries/Spain/g3-tones.xml'), + Array('request' => '320x196x4/Chan-SCCP-b.png', 'expected' => '/data/wallpapers/320x196x4/Chan-SCCP-b.png'), + Array('request' => 'XMLDefault.cnf.xml', 'expected' => '/data/settings/XMLDefault.cnf.xml'), Array('request' => '../XMLDefault.cnf.xml', 'expected' => ResolveResult::RequestContainsPathWalk), Array('request' => 'XMLDefault.cnf.xml/../../text.xml', 'expected' => ResolveResult::RequestContainsPathWalk), ); diff --git a/lib/utils.php b/lib/utils.php index 095d373..c93767f 100644 --- a/lib/utils.php +++ b/lib/utils.php @@ -2,6 +2,7 @@ // // Helper functions // +namespace SCCP\Utils; function utf8_urldecode($str) { $str = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($str)); diff --git a/lib/xml.php b/lib/xml.php index ee3c3ce..29ce5e0 100644 --- a/lib/xml.php +++ b/lib/xml.php @@ -1,4 +1,6 @@