diff --git a/config.ini b/config.ini
new file mode 100644
index 0000000..21f7036
--- /dev/null
+++ b/config.ini
@@ -0,0 +1,17 @@
+[main]
+debug = on ; The output in the browser window for more information
+cache_filename = "/tmp/provision_sccp_resolver.cache"
+default_language = English_United_States
+log_type = SYSLOG ; SYSLOG|STDERR|STDOUT|NULL|FILE
+log_level = LOG_INFO ; LOG_EMERG|LOG_ALERT|LOG_CRIT|LOG_ERR|LOG_WARNING|LOG_NOTICE|LOG_INFO|LOG_DEBUG
+;log_filename = provision.log ; only in case of log_type = FILE
+
+[subdirs]
+tftproot = tftpboot
+firmware = firmware
+settings = settings
+wallpapers = wallpapers
+ringtones = ringtones
+locales = locales
+countries = countries
+languages = languages
diff --git a/etc/nginx/sites-available/tftpboot b/etc/nginx/sites-available/tftpboot
index 23f3772..9d9c4ce 100644
--- a/etc/nginx/sites-available/tftpboot
+++ b/etc/nginx/sites-available/tftpboot
@@ -1,260 +1,29 @@
server {
- listen 6970;
- server_name tftp.servername.org;
- #root /tftpboot;
- root /data/development/sccp/sources/tftp/tftpboot;
- index XMLDefault.cnf.xml;
+ listen 6970;
+ server_name tftp.servername.org;
+ root /data/development/sccp/sources/tftp/tftpboot;
- # Normal Logging
- #access_log /var/log/nginx/tftp.access.log;
- #error_log /var/log/nginx/tftp.error.log;
+ # Normal Logging
+ access_log /var/log/nginx/tftp1.access.log;
+ error_log /var/log/nginx/tftp1.error.log;
- # Debug Rewrite Rules
- rewrite_log on;
- access_log /var/log/nginx/tftp.access.log;
- error_log /var/log/nginx/tftp.error.log notice;
+ index index.php;
+ location ~ \.php$ {
+ fastcgi_split_path_info ^(.+\.php)(/.+)$;
+ fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
- location / {
- # settings
- rewrite ^/((.*)(\.cnf\.xml|\.tlv|authorized_keys)(\.enc)?(\.sgn)?)$ /settings/$1 last;
+ location / {
+ try_files $uri $uri/ /index.php$is_args$args;
+ rewrite ^/(.*)$ /index.php?filename=$1 last;
+ }
- # firmware
- rewrite ^/((.*).(bin|bin.|loads|LOADS|sbn|SBN|sb2|sbin|zz|zup)(\.sgn)?)$ /firmware/$1 last;
-
- # locales
- rewrite ^/(.*)/((.*)-tones\.xml(\.sgn)?)$ /locales/countries/$1/$2 last;
- rewrite ^/(.*)/((.*)(-dictionary(.*)\.xml)(\.sgn)?)$ /locales/languages/$1/$2 last;
- rewrite ^/(.*)/((.*)(-kate(.*)\.xml)(\.sgn)?)$ /locales/languages/$1/$2 last;
- rewrite ^/(.*)/((.*)(-sccp\.jar)(\.sgn)?)$ /locales/languages/$1/$2 last;
- rewrite ^/(.*)/((.*)(-font\.xml)(\.sgn)?)$ /locales/languages/$1/$2 last;
- rewrite ^/(.*)/(CIPC_Locale\.(.*))(\.sgn)?)$ /locales/languages/$1/$2 last;
-
- rewrite ^/(.*)/((.*)(-tones.xml)(\.sgn)?)$ /locales/countries/$1/$2 last;
-
- # ringtones
- rewrite ^/([D|d]istinctive)?([R|r]ing[L|l]ist)\.(xml|XML)(\.sgn)?$ /ringtones/ringlist.xml last;
- #rewrite ^/((.*)(\.raw|\.pcm)(\.sgn))?$ /ringtones/$1 last;
-
- # wallpapers
- rewrite ^/Desktops/(.*)/((.*)(\.sgn)?)$ /wallpapers/$1/$2 last;
- try_files $uri $uri/ =404;
- autoindex off;
- }
-
- # settings
- location /settings {
- try_files $uri $uri/ =404;
- autoindex off;
- }
-
- # firmware
- location /firmware {
- # 6901 firmware (java-based)
- rewrite ^/firmware/(APP6901SCCP.+\.sgn)$ /firmware/6901/$1 last;
- rewrite ^/firmware/(KNL6901SCCP.+\.sgn)$ /firmware/6901/$1 last;
- rewrite ^/firmware/(SCCP6901.+\.loads)$ /firmware/6901/$1 last;
-
- # 6911 firmware (java-based)
- rewrite ^/firmware/(APP6911SCCP.+\.sgn)$ /firmware/6911/$1 last;
- rewrite ^/firmware/(BFS6911SCCP.+\.sgn)$ /firmware/6911/$1 last;
- rewrite ^/firmware/(KNL6911SCCP.+\.sgn)$ /firmware/6911/$1 last;
- rewrite ^/firmware/(SCCP6911.+\.loads)$ /firmware/6911/$1 last;
-
- # 6921 firmware (java-based)
- rewrite ^/firmware/(BOOT69xx.+\.sgn)$ /firmware/6921/$1 last;
- rewrite ^/firmware/(DSP69xx.+\.sgn)$ /firmware/6921/$1 last;
- rewrite ^/firmware/(SCCP69xx.+\.loads)$ /firmware/6921/$1 last;
- rewrite ^/firmware/(SCCP69xx.+\.sgn)$ /firmware/6921/$1 last;
-
- # 6945 firmware (java-based)
- rewrite ^/firmware/(SCCP6945.+\.sgn)$ /firmware/6945/$1 last;
- rewrite ^/firmware/(SCCP6945.+\.loads)$ /firmware/6945/$1 last;
-
- # 69xx firmware (java-based)
- rewrite ^/firmware/(BOOT69xx.+\.sgn)$ /firmware/69xx/$1 last;
- rewrite ^/firmware/(DSP69xx.+\.sgn)$ /firmware/69xx/$1 last;
- rewrite ^/firmware/(SCCP69xx.+\.loads)$ /firmware/69xx/$1 last;
- rewrite ^/firmware/(SCCP69xx.+\.sgn)$ /firmware/69xx/$1 last;
-
- # 7902 firmware (ancient)
- rewrite ^/firmware/(CP7902080002SCCP060817A.sbin)$ /firmware/7902/$1 last;
-
- # 7905 firmware (ancient)
- rewrite ^/firmware/(CP7905080003SCCP070409A.sbin)$ /firmware/7905/$1 last;
- rewrite ^/firmware/(CP7905080003SCCP070409A.zup)$ /firmware/7905/$1 last;
-
- # 7906_7911 firmware (java-based)
- rewrite ^/firmware/(apps11.+\.sbn)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(cnu11.+\.sbn)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(cvm11sccp.+\.sbn)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(dsp11.+\.sbn)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(jar11sccp.+\.sbn)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(SCCP11.+\.loads)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(term06.+\.loads)$ /firmware/7906_7911/$1 last;
- rewrite ^/firmware/(term11.+\.loads)$ /firmware/7906_7911/$1 last;
-
- # 7910 firmware (ancient)
- rewrite ^/firmware/(P00405000700.bin)$ /firmware/7910/$1 last;
- rewrite ^/firmware/(P00405000700.sbn)$ /firmware/7910/$1 last;
-
- # 7912 firmware (ancient)
- rewrite ^/firmware/(CP7912080004SCCP080108A.sbin)$ /firmware/7912/$1 last;
-
- # 7915 firmware (ancient)
- rewrite ^/firmware/(B015-1-0-4.SBN)$ /firmware/7915/$1 last;
-
- # 7916 firmware (ancient)
- rewrite ^/firmware/(B016-1-0-4.SBN)$ /firmware/7916/$1 last;
-
- # 7920 firmware (ancient)
- rewrite ^/firmware/(cmterm_7920.4.0-03-02.bin)$ /firmware/7920/$1 last;
-
- # 7921_7925 firmware (ancient)
- rewrite ^/firmware/(APPS-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
- rewrite ^/firmware/(CP7921G-1.4.3.4.LOADS)$ /firmware/7921_7925/$1 last;
- rewrite ^/firmware/(GUI-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
- rewrite ^/firmware/(SYS-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
- rewrite ^/firmware/(TNUX-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
- rewrite ^/firmware/(TNUXR-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
- rewrite ^/firmware/(WLAN-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
-
- # 7926 firmware (ancient)
- rewrite ^/firmware/(APPSS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(CP7926G-1.4.1SR1.LOADS)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(EA15FW-BF3-220.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(GUIS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(JSYSS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(JUIS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(SYSS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(TNUXRS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(TNUXS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
- rewrite ^/firmware/(WLANS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
-
- # 7931 firmware (java-based)
- rewrite ^/firmware/(apps31.+\.sbn)$ /firmware/7931/$1 last;
- rewrite ^/firmware/(cnu31.+\.sbn)$ /firmware/7931/$1 last;
- rewrite ^/firmware/(cvm31sccp.+\.sbn)$ /firmware/7931/$1 last;
- rewrite ^/firmware/(dsp31.+\.sbn)$ /firmware/7931/$1 last;
- rewrite ^/firmware/(jar31sccp.+\.sbn)$ /firmware/7931/$1 last;
- rewrite ^/firmware/(SCCP31.+\.loads)$ /firmware/7931/$1 last;
- rewrite ^/firmware/(term31.+\.loads)$ /firmware/7931/$1 last;
-
- # 7935 firmware (ancient)
- rewrite ^/firmware/(P00503021900.bin)$ /firmware/7935/$1 last;
-
- # 7936 firmware (ancient)
- rewrite ^/firmware/(cmterm_7936.3-3-21-0.bin)$ /firmware/7936/$1 last;
-
- # 7937 firmware (ancient)
- rewrite ^/firmware/(apps37sccp.1-4-5-7.bin)$ /firmware/7937/$1 last;
-
- # 7940_7960 firmware (ancient)
- rewrite ^/firmware/(P0030801SR.+\.bin)$ /firmware/7940_7960/$1 last;
- rewrite ^/firmware/(P0030801SR.+\.loads)$ /firmware/7940_7960/$1 last;
- rewrite ^/firmware/(P0030801SR.+\.sb2)$ /firmware/7940_7960/$1 last;
- rewrite ^/firmware/(P0030801SR.+\.sbn)$ /firmware/7940_7960/$1 last;
-
- # 7941_7961 firmware (java-based)
- rewrite ^/firmware/(apps41.+\.sbn)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(cnu41.+\.sbn)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(cvm41sccp.+\.sbn)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(dsp41.+\.sbn)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(jar41sccp.+\.sbn)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(SCCP41.+\.loads)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(term41.+\.loads)$ /firmware/7941_7961/$1 last;
- rewrite ^/firmware/(term61.+\.loads)$ /firmware/7941_7961/$1 last;
-
- # 7942_7962 firmware (java-based)
- rewrite ^/firmware/(apps42.+\.sbn)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(cnu42.+\.sbn)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(cvm42sccp.+\.sbn)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(dsp42.+\.sbn)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(jar42sccp.+\.sbn)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(SCCP42.+\.loads)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(term42.+\.loads)$ /firmware/7942_7962/$1 last;
- rewrite ^/firmware/(term62.+\.loads)$ /firmware/7942_7962/$1 last;
-
- # 7945_7965 firmware (java-based)
- rewrite ^/firmware/(apps45.+\.sbn)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(cnu45.+\.sbn)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(cvm45sccp.+\.sbn)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(dsp45.+\.sbn)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(jar45sccp.+\.sbn)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(SCCP45.+\.loads)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(term45.+\.loads)$ /firmware/7945_7965/$1 last;
- rewrite ^/firmware/(term65.+\.loads)$ /firmware/7945_7965/$1 last;
-
- # 7970_7971 firmware (java-based)
- rewrite ^/firmware/(apps70.+\.sbn)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(cnu70.+\.sbn)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(cvm70sccp.+\.sbn)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(dsp70.+\.sbn)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(jar70sccp.+\.sbn)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(SCCP70.+\.loads)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(term70.+\.loads)$ /firmware/7970_7971/$1 last;
- rewrite ^/firmware/(term71.+\.loads)$ /firmware/7970_7971/$1 last;
-
- # 7975 firmware (java-based)
- rewrite ^/firmware/(apps75.+\.sbn)$ /firmware/7975/$1 last;
- rewrite ^/firmware/(cnu75.+\.sbn)$ /firmware/7975/$1 last;
- rewrite ^/firmware/(cvm75sccp.+\.sbn)$ /firmware/7975/$1 last;
- rewrite ^/firmware/(dsp75.+\.sbn)$ /firmware/7975/$1 last;
- rewrite ^/firmware/(jar75sccp.+\.sbn)$ /firmware/7975/$1 last;
- rewrite ^/firmware/(SCCP75.+\.loads)$ /firmware/7975/$1 last;
- rewrite ^/firmware/(term75.+\.loads)$ /firmware/7975/$1 last;
-
- # 7985 firmware (ancient)
- rewrite ^/firmware/(cmterm_7985.4-1-7-0.bin)$ /firmware/7985/$1 last;
-
- # 894x firmware (java-based)
- rewrite ^/firmware/(BOOT894x.+\.sgn)$ /firmware/894x/$1 last;
- rewrite ^/firmware/(SCCP894x.+\.sgn)$ /firmware/894x/$1 last;
- rewrite ^/firmware/(SCCP894x.+\.loads)$ /firmware/894x/$1 last;
-
- # ata186 firmware (ancient)
- rewrite ^/firmware/(ATA030204SCCP090202A.zup)$ /firmware/ata186/$1 last;
-
- # ata188 firmware (ancient)
- rewrite ^/firmware/(ATA030204SCCP090202A.zup)$ /firmware/ata188/$1 last;
-
- # SPA50x
- rewrite ^/firmware/(spa50x.+\.bin)$ /firmware/spa50x/$1 last;
- rewrite ^/firmware/(spa51x.+\.bin)$ /firmware/spa51x/$1 last;
- rewrite ^/firmware/(spa515.+\.bin)$ /firmware/spa525/$1 last;
- rewrite ^/firmware/(spa941.+\.bin)$ /firmware/spa941/$1 last;
-
- try_files $uri $uri/ =404;
- autoindex off;
- }
-
- # locales
-
- location /locales {
- try_files $uri $uri/ =404;
- autoindex off;
- }
-
- # ringtones
- location /ringtones {
- try_files $uri $uri/ =404;
- autoindex off;
- }
-
- # wallpapers
- location /wallpapers {
- try_files $uri $uri/ =404;
- autoindex off;
- }
-
- # Deny access to .htaccess
- location ~ /\.ht {
- deny all;
- }
-
- error_page 404 /;
-
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root /usr/share/nginx/html;
- }
+ error_page 404 /;
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
}
diff --git a/lib/config.php b/lib/config.php
new file mode 100644
index 0000000..0106c13
--- /dev/null
+++ b/lib/config.php
@@ -0,0 +1,80 @@
+ Array(
+ 'debug' => 1,
+ 'default_language' => 'English_United_States',
+ 'log_type' => "NULL",
+ 'log_level' => LOG_EMERG
+ ),
+ 'subdirs' => Array(
+ 'tftproot' => 'tftpboot',
+ 'firmware' => 'firmware',
+ 'settings' => 'settings',
+ 'wallpapers' => 'wallpapers',
+ 'ringtones' => 'ringtones',
+ 'locales' => 'locales',
+ 'countries' => 'countries',
+ 'languages' => 'languages',
+ )
+);
+$tree_base = Array(
+ 'settings' => array('path' => 'tftproot', "strip" => TRUE),
+ 'wallpapers' => array('path' => 'tftproot', "strip" => FALSE),
+ 'ringtones' => array('path' => 'tftproot', "strip" => TRUE),
+ 'locales' => array('path' => 'tftproot', "strip" => TRUE),
+ 'firmware' => array('path' => 'tftproot', "strip" => TRUE),
+ 'languages' => array('path' => 'locales', "strip" => FALSE),
+ 'countries' => array('path' => 'locales', "strip" => FALSE),
+ 'default_language' => array('path' => 'locales', "strip" => TRUE),
+);
+
+# Merge config
+$ini_array = parse_ini_file('../config.ini', TRUE, INI_SCANNER_TYPED);
+if (!empty($ini_array)) {
+ $config = array_merge($base_config, $ini_array);
+}
+
+# build new config['subdirs'] paths substituting bases from tree_base
+foreach ($tree_base as $key => $value) {
+ $tmp = $config;
+ if (!empty($tmp['subdirs'][$key])) {
+ if (substr($tmp['subdirs'][$key], 0, 1) !== "/") {
+ if (is_array($tmp['subdirs'][$value['path']])) {
+ $path = $tmp['subdirs'][$value['path']]['path'].'/'.$tmp['subdirs'][$key];
+ } else {
+ $path = $tmp['subdirs'][$value['path']].'/'.$tmp['subdirs'][$key];
+ }
+ }
+ $config['subdirs'][$key] = array('path' => $path, 'strip' => $value['strip']);
+ }
+}
+
+$config['main']['base_path'] = $base_path;
+$config['main']['tftproot'] = (!empty($config['main']['tftproot'])) ? $base_path . "tftpboot" : '/tftpboot';
+
+switch($config['main']['log_type']) {
+ case 'SYSLOG':
+ $logger = new Logger_Syslog($config['main']['log_level']);
+ break;
+ case 'FILE':
+ if (!isempty($config['main']['log_file'])) {
+ $logger = new Logger_Filename($config['main']['log_level'], $config['main']['log_file']);
+ }
+ break;
+ case 'STDOUT':
+ $logger = new Logger_Stdout($config['main']['log_level']);
+ break;
+ case 'STDERR':
+ $logger = new Logger_Stderr($config['main']['log_level']);
+ break;
+ default:
+ $logger = new Logger_Null($config['main']['log_level']);
+}
+
+# Fixup debug
+$print_debug = (!empty($config['main']['debug'])) ? $config['main']['debug'] : 'off';
+$print_debug = ($print_debug == 1) ? 'on' : $print_debug;
+?>
diff --git a/lib/logger.php b/lib/logger.php
new file mode 100644
index 0000000..249d121
--- /dev/null
+++ b/lib/logger.php
@@ -0,0 +1,94 @@
+minimum = $minimum;
+ }
+
+ function shouldlog($priority)
+ {
+ // Note: this looks reversed, but is correct
+ // the priority must be AT LEAST the minimum,
+ // because higher priorities represent lower numbers.
+ return $priority <= $this->minimum;
+ }
+
+ abstract function log($priority, $message);
+}
+
+class Logger_Null extends Logger
+{
+ function log($priority, $message)
+ {
+ }
+}
+
+class Logger_Syslog extends Logger
+{
+ function log($priority, $message)
+ {
+ if($this->shouldlog($priority))
+ syslog($priority,$message);
+ }
+}
+
+class Logger_Filehandle extends Logger
+{
+ private $priority_map = array(
+ LOG_DEBUG => "D",
+ LOG_INFO => "I",
+ LOG_NOTICE => "N",
+ LOG_WARNING => "W",
+ LOG_ERR => "E",
+ LOG_CRIT => "C",
+ LOG_ALERT => "A",
+ LOG_EMERG => "!"
+ );
+ function __construct($minimum, $filehandle, $dateformat = "r")
+ {
+ $this->filehandle = $filehandle;
+ $this->dateformat = $dateformat;
+ return parent::__construct($minimum);
+ }
+
+ function log($priority, $message)
+ {
+ if($this->shouldlog($priority))
+ fwrite($this->filehandle, date($this->dateformat) . ": " . $this->priority_map[$priority] . " $message\n");
+ }
+}
+
+class Logger_Filename extends Logger_Filehandle
+{
+ function __construct($minimum, $filename, $dateformat = "r")
+ {
+ return parent::__construct($minimum, fopen($filename, "a"), $dateformat);
+ }
+}
+
+class Logger_Stderr extends Logger_Filehandle
+{
+ function __construct($minimum, $dateformat = "r")
+ {
+ return parent::__construct($minimum, STDERR, $dateformat);
+ }
+}
+class Logger_Stdout extends Logger_Filehandle
+{
+ function __construct($minimum, $dateformat = "r")
+ {
+ return parent::__construct($minimum, STDOUT, $dateformat);
+ }
+}
+?>
\ No newline at end of file
diff --git a/lib/resolver.php b/lib/resolver.php
new file mode 100644
index 0000000..579b10b
--- /dev/null
+++ b/lib/resolver.php
@@ -0,0 +1,168 @@
+config = $config;
+ //$this->logger = $logger;
+ if(file_exists($this->config['main']['cache_filename'])) {
+ $this->cache = unserialize(file_get_contents($config['main']['cache_filename']));
+ } else {
+ $this->buildCleanCache();
+ }
+ }
+ function __destruct() {
+ // $this->printCache()
+ if ($this->isDirty) {
+ if (!file_put_contents($this->config['main']['cache_filename'], serialize($this->cache))) {
+ $this->log_error_and_throw("Could not write to file '".$this->config['cache_filename']."' at Resolver::destruct");
+ }
+ }
+ }
+ function log_error_and_throw($message) {
+ global $logger;
+ $logger->log('LOG_ERROR', $message);
+ throw new Exception($message);
+ }
+ function log_debug($message) {
+ global $logger;
+ $logger->log('LOG_DEBUG', $message);
+ }
+ function searchForFile($filename) {
+ foreach($this->config['subdirs'] as $key => $value) {
+ if ($key === "firmware" || $key === "tftproot" ) {
+ continue;
+ }
+ $path = realpath($this->config['main']['base_path'] . "/" . $value['path'] . "/$filename");
+ if (file_exists($path)) {
+ $this-> addFile($filename, $path);
+ return $path;
+ }
+ }
+ $this->log_error_and_throw("File '$filename' does not exist");
+ }
+ function buildCleanCache() {
+ foreach($this->config['subdirs'] as $key =>$value) {
+ if ($key === "tftproot") {
+ continue;
+ }
+ $path = $this->config['main']['base_path'] . "/" . $value['path'] . "/";
+ $dir_iterator = new RecursiveDirectoryIterator($path);
+ $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
+ foreach ($iterator as $file) {
+ if ($file->isFile()) {
+ if ($value['strip']) {
+ $this->addFile($file->getFileName(), $file->getPathname());
+ } else {
+ $subdir = basename(dirname($file->getPathname()));
+ $this->addFile('$subpath/'.$file->getFileName(), $file->getPathname());
+ }
+ }
+ }
+ }
+ $this->isDirty = TRUE;
+ }
+ function addFile($requestpath, $truepath) {
+ //$this->logger->log('LOG_DEBUG', "Adding $requestpath");
+ $this->log_debug("Adding $requestpath");
+ $this->cache[$requestpath] = $truepath;
+ $this->isDirty =TRUE;
+ }
+ function removeFile($requestpath) {
+ $this->log_debug("Removing $hash");
+ unset($this->cache[$requestpath]);
+ $this->isDirty = TRUE;
+ }
+ function validateRequest($request) {
+ /* make sure request does not startwith or contain: "/", "../" or "/./" */
+ /* make sure request only starts with filename or one of $config[$subdir]['locale'] or $config[$subdir]['wallpaper'] */
+ /* check uri/url decode */
+ if (!is_string($request)) {
+ $this->log_error_and_throw("Request is not a string");
+ }
+ $this->log_debug($request . ":" . escapeshellarg($request) . ":" . utf8_urldecode($request) . "\n");
+ $escaped_request = escapeshellarg(utf8_urldecode($request));
+ if ($escaped_request !== "'" . $request . "'") {
+ $this->log_error_and_throw("Request '$request' contains invalid characters");
+ }
+ if (strstr($escaped_request, "..")) {
+ $this->log_error_and_throw("Request '$request' containst '..'");
+ }
+ }
+ function resolve($request) /* canthrow */ {
+ $this->validateRequest($request);
+ $path = '';
+ if (array_key_exists($request, $this->cache)) {
+ if ($path = $this->cache[$request]) {
+ if (!file_exists($path)) {
+ $this->removeFile($request);
+ $this->log_error_and_throw("File '$request' does not exist on FS");
+ }
+ return $path;
+ }
+ }
+ if ($this->searchForFile($request)) {
+ return $this->cache[$request];
+ }
+ return $path;
+ }
+ /* temporary */
+ function printCache() {
+ print_r($this->cache);
+ }
+}
+
+// Testing
+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', 'throws' => FALSE),
+ Array('request' => 'Russian_Russian_Federation/be-sccp.jar', 'expected' => '/tftpboot/locales/languages/Russian_Russian_Federation/be-sccp.jar', 'throws' => FALSE),
+ Array('request' => 'Spain/g3-tones.xml', 'expected' => '/tftpboot/locales/countries/Spain/g3-tones.xml', 'throws' => FALSE),
+ Array('request' => '320x196x4/Chan-SCCP-b.png', 'expected' => '/tftpboot/wallpapers/320x196x4/Chan-SCCP-b.png', 'throws' => FALSE),
+ Array('request' => 'XMLDefault.cnf.xml', 'expected' => '/tftpboot/settings/bak/XMLDefault.cnf.xml', 'throws' => FALSE),
+ Array('request' => '../XMLDefault.cnf.xml', 'expected' => '', 'throws' => TRUE),
+ Array('request' => 'XMLDefault.cnf.xml/../../text.xml', 'expected' => '', 'throws' => TRUE),
+
+ );
+ foreach($test_cases as $test) {
+ try {
+ $result = $resolver->resolve($test['request']);
+ if ($result !== $base_path . $test['expected']) {
+ print("Error: expected result does not match what we got\n");
+ print("request:'".$test['request']."', result:'" . $base_path . $test['expected'] . "'\n");
+ } else {
+ print("'" . $test['request'] . "' => '" . $result . "'\n");
+ }
+ } catch (Exception $e) {
+ if (!$test['throws']) {
+ print("Error: request was expected to throw: $e\n");
+ } else {
+ print("'" . $test['request'] . "' => throws error as expected\n");
+ }
+ }
+ }
+ unset($resolver);
+ #unlink($CACHEFILE_NAME);
+}
+?>
diff --git a/lib/utils.php b/lib/utils.php
new file mode 100644
index 0000000..28e7652
--- /dev/null
+++ b/lib/utils.php
@@ -0,0 +1,10 @@
+
diff --git a/tftpboot/index.cnf b/tftpboot/index.cnf
deleted file mode 100644
index 9ec78d3..0000000
--- a/tftpboot/index.cnf
+++ /dev/null
@@ -1,13 +0,0 @@
-[main]
-debug = on ; The output in the browser window for more information
-tftproot = /tftpboot
-;default_language = English_United_States
-
-firmware = firmware
-settings = settings
-wallpapers = wallpapers
-ringtones = ringtones
-locales = locales
-countries = countries
-languages = languages
-;log = /tftpboot/provision.log
diff --git a/tftpboot/index.php b/tftpboot/index.php
index 495d0ce..c7024b3 100644
--- a/tftpboot/index.php
+++ b/tftpboot/index.php
@@ -1,308 +1,67 @@
1,
- 'tftproot' => $base_path,
- 'default_language' => 'English_United_States',
- 'firmware' => 'firmware', 'settings' => 'settings', 'wallpapers' => 'wallpapers', 'ringtones' => 'ringtones',
- 'locales' => 'locales', 'countries' => 'countries', 'languages' => 'languages'
-);
-$base_tree = Array('settings' => 'tftproot', 'wallpapers' => 'tftproot', 'ringtones'=>'tftproot',
- 'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales',
- 'countries' => 'locales', 'default_language' => 'locales');
-
-# Merge config
-$ini_array = parse_ini_file('index.cnf');
-if (!empty($ini_array)) {
- $config = array_merge($base_config, $ini_array);
+function send_fallback_html($message) {
+ while (ob_get_level()) {ob_end_clean();}
+ if (ob_get_length() === false) {
+ ob_start();
+ header('Content-Description: README');
+ header('Content-Type: text/html');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate');
+ header('Pragma: public');
+ }
+ $content="
+
+
Request:" . json_encode($request) . "
+Message:" . $message . "
+ + + "; + print ($content); + ob_flush(); + flush(); } -foreach ($base_tree as $key => $value) { - if (!empty($config[$key])) { - if (substr($config[$key],0,1) != "/") { - $config[$key] = $config[$value].'/'.$config[$key]; - } - } +function sendfile($file) { + if (file_exists($file)) { + while (ob_get_level()) {ob_end_clean();} + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename=' . basename($file)); + header('Content-Transfer-Encoding: binary'); + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + header('Content-Length: ' . filesize($file)); + + /* want to stream out, so don't use file_get_contents() in this case */ + if ($fd = fopen($file, 'rb')) { + while (!feof($fd)) { + print fread($fd, 1024); + } + fclose($fd); + } + } } - -#$config['tftproot'] = (!empty($config['tftproot'])) ? $config['tftproot'] : '/tftpboot'; - -# Fixup debug -$print_debug = (!empty($config['debug'])) ? $config['debug'] : 'off'; -$print_debug = ($print_debug == 1) ? 'on' : $print_debug; - -# Parse request -$request = $_REQUEST; -$req_file = !empty($request['id']) ? $request['id'] : ''; - -# directory content extensions map -$fw_suffix = array('.bin', '.loads', '.sbn', '.sb2', '.sbin', '.zz', '.zup', '.loads'); - -//$settings_suffix = array('cnf.xml'); - -$ringtones_list = array('distinctive.xml', 'ringlist.xml','distinctiveringlist.xml'); -$ringtones_suffix = array('.raw', '.pcm', '.rwb'); - -$locale_list = array('-dictionary.', 'dictionary-ext.', '-dictionary.utf-8.', '-kate.xml', '-font.xml', '-font.dat','-tones.xml', - 'be-sccp.jar', 'tc-sccp.jar', 'td-sccp.jar', 'ipc-sccp.jar', 'mk-sccp.jar', '_locale.loads', 'i-button-help.xml', - 'tc-sip.jar', 'td-sipp.jar'); - -# Show debug output -if ($print_debug == 'on') { - print_r(""); - print_r($config); - print(""); - print_r("
"); - print_r($request); - print(""); +if (!$request || empty($request) || !array_key_exists('filename',$request) || empty($request['filename'])) { + send_fallback_html("Empty request sent"); + exit(); } - -# Start parsing the request -$req_file_full_path = '' ; - -if (!empty($req_file)) { - $signed = FALSE; - $req_data_ar = explode('/', $req_file); - $req_data_len = count($req_data_ar) - 1; - - $orig_req_file_name = end($req_data_ar); - $req_file_name = $orig_req_file_name; - - if (strpos('.sgn;', strtolower($orig_req_file_name).';') !== FALSE) { // handle signed files - $signed = TRUE; - $req_file_name = basename($orig_req_file_name, '.sgn'); // strip signed part - } - - - if (file_exists($config['tftproot'].'/'.$req_file_name)) // prevent "/../...//" browsing - (eliminate back door) - { - $req_file_full_path = $config['tftproot'].'/'.$req_file_name; - } - else - { - $tmp_file = explode('.', $req_file_name); - - if (strpos_array($req_file_name, $fw_suffix,'any') !== FALSE) { // Firmware file was requested - $firmware_list = find_all_files($config['firmware']); - $pos2 = strpos_array($firmware_list, $req_file_name, 'any'); // case unsensitive - if ($pos2 !== FALSE) { // Request Firmware - $req_file_full_path = $firmware_list[$pos2]; - } - if ($print_debug == 'on'){ print_r('