/**
* General functions library
*
- * @author Roland Haeder <webmaster@ship-simu.org>
+ * @author Roland Haeder <webmaster@shipsimu.org>
* @version 3.0.0
- * @copyright Copyright (c) 2009 Cracker Tracker Team
+ * @copyright Copyright (c) 2009 - 2017 Cracker Tracker Team
* @license GNU GPL 3.0 or any newer version
- * @link http://www.ship-simu.org
+ * @link http://www.shipsimu.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
if (!function_exists('implode_r')) {
// Implode recursive a multi-dimension array, taken from www.php.net
function implode_r ($glue, $array, $array_name = NULL) {
- $return = array();
- while(list($key,$value) = @each($array)) {
- if(is_array($value)) {
+ $return = [];
+ while (list($key,$value) = @each($array)) {
+ if (is_array($value)) {
// Is an array again, so call recursive
$return[] = implode_r($glue, $value, (string) $key);
} else {
- if($array_name != NULL) {
+ if ($array_name != NULL) {
$return[] = $array_name . '[' . (string) $key . ']=' . $value . "\n";
} else {
$return[] = $key . '=' . $value."\n";
} // END - while
// Return resulting array
- return(implode($glue, $return));
+ return implode($glue, $return);
} // END - function
} // END - if
if (!function_exists('implode_secure')) {
// Implode a simple array with a 'call-back' to our escaper function
- function implode_secure ($array) {
+ function implode_secure (array $array) {
// Return string
$return = '';
} // END - function
} // END - if
-// Getter for ctracker_debug
+// Load configuration, if found
+function crackerTrackerLoadConfiguration () {
+ // FQFN
+ $fqfn = sprintf('%s/config/db_config.php', $GLOBALS['ctracker_base_path']);
+
+ // Is the file readable?
+ if (!isCrackerTrackerFileFound($fqfn)) {
+ // No config file found
+ die(__FUNCTION__.': No configuration file found.');
+ } // END - if
+
+ // Load it
+ require $fqfn;
+
+ // Load email header
+ $GLOBALS['ctracker_header'] = crackerTrackerLoadEmailTemplate('header');
+}
+
+// Getter for ctracker_debug_enabled
function isCrackerTrackerDebug () {
// Is it set?
- return ((isset($GLOBALS['ctracker_debug'])) && ($GLOBALS['ctracker_debug'] === true));
+ $result = ((isset($GLOBALS['ctracker_debug_enabled'])) && ($GLOBALS['ctracker_debug_enabled'] === TRUE));
+
+ // Debug message
+ //* DEBUG: */ error_log('result=' . intval($result));
+
+ // Return it
+ return $result;
+}
+
+// Determines the real remote address
+function determineCrackerTrackerRealRemoteAddress () {
+ // Initial value
+ $address = '0.0.0.0';
+
+ // Is a proxy in use?
+ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+ // Proxy was used
+ $address = trim($_SERVER['HTTP_X_FORWARDED_FOR']);
+ } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
+ // Yet, another proxy
+ $address = trim($_SERVER['HTTP_CLIENT_IP']);
+ } elseif (isset($_SERVER['REMOTE_ADDR'])) {
+ // The regular address when no proxy was used
+ $address = trim(getenv('REMOTE_ADDR'));
+ }
+
+ if ($address == 'unknown') {
+ // Invalid IP somehow given
+ $address = '0.0.0.0';
+ } elseif (strstr($address, ',')) {
+ // This strips out the real address from proxy output
+ $addressArray = explode(',', $address);
+ $address = $addressArray[0];
+ }
+
+ // Return the result
+ return $address;
+}
+
+// Determine if a proxy was used
+function isCrackerTrackerProxyUsed () {
+ // Check if specific entries are set
+ $proxyUsed = ((isset($_SERVER['HTTP_X_FORWARDED_FOR'])) || (isset($_SERVER['HTTP_CLIENT_IP'])));
+
+ // Return result
+ return $proxyUsed;
+}
+
+// Detects the user-agent string
+function crackerTrackerUserAgent ($sanitize = FALSE) {
+ // Default is 'unknown'
+ $ua = 'unknown';
+
+ // Is the entry there?
+ if (isset($_SERVER['HTTP_USER_AGENT'])) {
+ // Then use it securely
+ $ua = crackerTrackerSecureString(urldecode($_SERVER['HTTP_USER_AGENT']));
+ } // END - if
+
+ // Sanitize it?
+ if ($sanitize === TRUE) {
+ // Sanitize ...
+ $ua = crackerTrackerSanitize($ua);
+ } // END - if
+
+ // Return it
+ return $ua;
+}
+
+// Detects the script name
+function crackerTrackerScriptName ($sanitize = FALSE) {
+ // Default is NULL
+ $scriptName = NULL;
+
+ // Is it there?
+ if (!empty($_SERVER['SCRIPT_NAME'])) {
+ // Return NULL
+ $scriptName = crackerTrackerSecureString($_SERVER['SCRIPT_NAME']);
+ } // END - if
+
+ // Sanitize it?
+ if ($sanitize === TRUE) {
+ // Sanitize ...
+ $scriptName = crackerTrackerSanitize($scriptName);
+ } // END - if
+
+ // Return
+ return $scriptName;
+}
+
+// Detects the query string
+function crackerTrackerQueryString ($sanitize = FALSE) {
+ // Default is NULL
+ $query = NULL;
+
+ // Is it there?
+ if (!empty($_SERVER['QUERY_STRING'])) {
+ // Get string escaped
+ $query = crackerTrackerEscapeString(urldecode($_SERVER['QUERY_STRING']));
+ } elseif (!empty($_SERVER['REQUEST_URI'])) {
+ // Get string escaped
+ $query = crackerTrackerEscapeString(urldecode($_SERVER['REQUEST_URI']));
+ }
+
+ // Sanitize it?
+ if ((!empty($query)) && ($sanitize === TRUE)) {
+ // Sanitize ...
+ $query = crackerTrackerSanitize($query);
+ } // END - if
+
+ // Return it
+ return $query;
+}
+
+// Detects the server's name
+function crackerTrackerServerName ($sanitize = FALSE) {
+ // Default is NULL
+ $serverName = NULL;
+
+ // Is it there?
+ if (!empty($_SERVER['SERVER_NAME'])) {
+ // Return NULL
+ $serverName = crackerTrackerSecureString($_SERVER['SERVER_NAME']);
+ } // END - if
+
+ // Sanitize it?
+ if ($sanitize === TRUE) {
+ // Sanitize ...
+ $serverName = crackerTrackerSanitize($serverName);
+ } // END - if
+
+ // Return it
+ return $serverName;
+}
+
+// Detects the referer
+function crackerTrackerReferer ($sanitize = FALSE) {
+ // Default is a dash
+ $referer = '-';
+
+ // Is it there?
+ if (!empty($_SERVER['HTTP_REFERER'])) {
+ // Then use it securely
+ $referer = crackerTrackerSecureString(urldecode($_SERVER['HTTP_REFERER']));
+ } // END - if
+
+ // Sanitize it?
+ if ($sanitize === TRUE) {
+ // Sanitize ...
+ $referer = crackerTrackerSanitize($referer);
+ } // END - if
+
+ // Return it
+ return $referer;
+}
+
+// Detects request method
+function crackerTrackerRequestMethod () {
+ // Default is NULL
+ $method = NULL;
+
+ // Is it set?
+ if (!empty($_SERVER['REQUEST_METHOD'])) {
+ // Then use it
+ $method = $_SERVER['REQUEST_METHOD'];
+ } // END - if
+
+ // Return it
+ return $method;
+}
+
+// Detects the scripts path
+function crackerTrackerScriptPath () {
+ // Should always be there!
+ $path = dirname(crackerTrackerScriptName()) . '/';
+
+ // Return detected path
+ return $path;
+}
+
+// Detects wether we have SSL
+function crackerTrackerSecured () {
+ // Detect it
+ $ssl = ((isset($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off'));
+
+ // Return result
+ return $ssl;
+}
+
+// Secures a string by escaping it and passing it through strip_tags,htmlentities-chain
+function crackerTrackerSecureString ($str) {
+ // First escape it
+ $str = crackerTrackerEscapeString($str);
+
+ // Then pass it through the functions
+ $str = htmlentities(strip_tags($str), ENT_QUOTES);
+
+ // Return it
+ return $str;
+}
+
+// Is the file there and readable?
+function isCrackerTrackerFileFound ($FQFN) {
+ // Simply check it
+ return ((file_exists($FQFN)) && (is_readable($FQFN)));
+}
+
+// Loads a given "template" (this is more an include file)
+function crackerTrackerLoadTemplate ($template) {
+ // Create the full-qualified filename (FQFN)
+ $FQFN = sprintf('%s/libs/templates/%s.tpl.php',
+ $GLOBALS['ctracker_base_path'],
+ $template
+ );
+
+ // Is this template found?
+ if (isCrackerTrackerFileFound($FQFN)) {
+ // Detect language
+ crackerTrackerLanguage();
+
+ // Load it
+ require_once($FQFN);
+ } else {
+ // Not found, so die here
+ crackerTrackerDie();
+ }
+}
+
+// Loads a given "template" (this is more an include file)
+function crackerTrackerLoadLocalizedTemplate ($template) {
+ // Create the full-qualified filename (FQFN)
+ $FQFN = sprintf('%s/libs/templates/%s/%s.tpl.php',
+ $GLOBALS['ctracker_base_path'],
+ getCrackerTrackerLanguage(),
+ $template
+ );
+
+ // Is this template found?
+ if (isCrackerTrackerFileFound($FQFN)) {
+ // Load it
+ require_once($FQFN);
+ } else {
+ // Not found, so die here
+ crackerTrackerDie();
+ }
+}
+
+// Detects the browser's language file and tries to load it, fall-back on english!
+function crackerTrackerLanguage () {
+ // Default is English
+ $GLOBALS['ctracker_language'] = 'en';
+ $weight = 1;
+
+ // Is the language string there?
+ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+ // Then detect it
+ foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang) {
+ // Split it again for q=x.x value
+ $langArray = explode(';', $lang);
+
+ // If there is an entry, we have a weight
+ if ((isset($langArray[1])) && ($langArray[1] > $weight)) {
+ // Use this language/weight instead
+ $GLOBALS['ctracker_language'] = $langArray[0];
+ $weight = $langArray[1];
+ } // END - if
+ } // END - foreach
+ } // END - if
+
+ // Construct FQFN
+ $FQFN = sprintf('%s/libs/language/%s.php',
+ $GLOBALS['ctracker_base_path'],
+ getCrackerTrackerLanguage()
+ );
+
+ // Is it not there, switch to "en"
+ if ((getCrackerTrackerLanguage() != 'en') && (!isCrackerTrackerFileFound($FQFN))) {
+ // English is default!
+ $GLOBALS['ctracker_language'] = 'en';
+
+ // Construct FQFN again
+ $FQFN = sprintf('%s/libs/language/en.php', $GLOBALS['ctracker_base_path']);
+ } // END - if
+
+ // Load the language file
+ require($FQFN);
+}
+
+// Loads a given email template and passes through $content
+function crackerTrackerLoadEmailTemplate ($template, array $content = [], $language = NULL) {
+ // Init language
+ crackerTrackerLanguage();
+
+ // Generate the FQFN
+ $FQFN = sprintf('%s/libs/mails/%s/%s.tpl',
+ $GLOBALS['ctracker_base_path'],
+ getCrackerTrackerLanguage($language),
+ $template
+ );
+
+ // So is the file there?
+ if (isCrackerTrackerFileFound($FQFN)) {
+ // Init result
+ $result = 'No result from template ' . $template . '. Please report this at http://forum.shipsimu.org Thank you.';
+
+ // Then load it
+ //* DEBUG-DIE: */ die('<pre>$result = "' . crackerTrackerCompileCode(trim(file_get_contents($FQFN))) . '";</pre>');
+ eval('$result = "' . crackerTrackerCompileCode(trim(file_get_contents($FQFN))) . '";');
+
+ // Return the result
+ return $result;
+ } else {
+ // Not found
+ crackerTrackerDie();
+ }
+}
+
+// Getter for message
+function getCrackerTrackerLocalized ($message) {
+ // Default message
+ $output = '!' . $message . '!';
+
+ // Is the language string there?
+ if (isset($GLOBALS['ctracker_localized'][$message])) {
+ // Use this instead
+ $output = $GLOBALS['ctracker_localized'][$message];
+ } // END - if
+
+ // Return it
+ return $output;
+}
+
+// Tries to find a message and outputs it
+function crackerTrackerOutputLocalized ($message) {
+ // Output it
+ print getCrackerTrackerLocalized($message);
+}
+
+// Compiles the given code
+function crackerTrackerCompileCode ($code) {
+ // Find all $content[foo]
+ preg_match_all('/\$(content|GLOBALS)((\[([a-zA-Z0-9-_]+)\])*)/', $code, $matches);
+
+ // Replace " with {QUOTE}
+ $code = str_replace('"', '{QUOTE}', $code);
+
+ // Replace all
+ foreach ($matches[0] as $key=>$match) {
+ // Replace it
+ if (substr($match, 0, 8) == '$GLOBALS') {
+ // $GLOBALS
+ $code = str_replace($match, "\" . \$GLOBALS['" . $matches[4][$key] . "'] . \"", $code);
+ } elseif (substr($match, 0, 8) == '$content') {
+ // $content
+ $code = str_replace($match, "\" . \$content['" . $matches[4][$key] . "'] . \"", $code);
+ }
+ } // END - foreach
+
+ // Return it
+ return $code;
+}
+
+// "Getter" for language
+function getCrackerTrackerLanguage ($lang = NULL) {
+ // Default is from browser
+ $language = $GLOBALS['ctracker_language'];
+
+ // Is $lang set?
+ if (!is_null($lang)) {
+ // Then use this instead
+ $language = $lang;
+ } // END - if
+
+ // Return it
+ return $language;
+}
+
+// "Getter" for ticket id
+function getCrackerTrackerTicketId () {
+ // Default is zero
+ $id = 0;
+
+ // Is it set?
+ if (isset($GLOBALS['ctracker_last_ticket']['ctracker_ticket'])) {
+ // Then use it
+ $id = $GLOBALS['ctracker_last_ticket']['ctracker_ticket'];
+ } // END - if
+
+ // Return the number
+ return $id;
+}
+
+// Sends a cookie to the user that he would not see this security warning again
+function sendCrackerTrackerCookie () {
+ // Set the cookie
+ // @TODO Why can't domain be set to value from crackerTrackerServerName() ?
+ setcookie('ctracker_ticket', getCrackerTrackerTicketId(), (time() + 60*60*24), '/', '', crackerTrackerSecured(), TRUE);
+ $_COOKIE['ctracker_ticket'] = getCrackerTrackerTicketId();
+}
+
+// Is the cookie set?
+function ifCrackerTrackerCookieIsSet () {
+ // Is it set and valid?
+ return ((isset($_COOKIE['ctracker_ticket'])) && ($_COOKIE['ctracker_ticket'] > 0));
+}
+
+// Redirects to the same URL
+function crackerTrackerRedirectSameUrl () {
+ // Construct the url
+ $url = '://' . crackerTrackerServerName() . crackerTrackerScriptName() . '?' . crackerTrackerQueryString();
+
+ // Do we have SSL?
+ if (crackerTrackerSecured()) {
+ // HTTPS
+ $url = 'https' . $url;
+ } else {
+ // HTTP
+ $url = 'http' . $url;
+ }
+
+ // And redirect
+ crackerTrackerSendRawRedirect($url);
}
-// [EOF]
-?>
+/**
+ * Send a HTTP redirect to the browser. This function was taken from DokuWiki
+ * (GNU GPL 2; http://www.dokuwiki.org) and modified to fit into this script.
+ *
+ * Works arround Microsoft IIS cookie sending bug. Does exit the script.
+ *
+ * @link http://support.microsoft.com/kb/q176113/
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @access private
+ */
+function crackerTrackerSendRawRedirect ($url) {
+ // Better remove any data by ctracker
+ unsetCtrackerData();
+
+ // always close the session
+ session_write_close();
+
+ // Revert entity &
+ $url = str_replace('&', '&', $url);
+
+ // check if running on IIS < 6 with CGI-PHP
+ if ((isset($_SERVER['SERVER_SOFTWARE'])) && (isset($_SERVER['GATEWAY_INTERFACE'])) &&
+ (strpos($_SERVER['GATEWAY_INTERFACE'],'CGI') !== FALSE) &&
+ (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) &&
+ ($matches[1] < 6)) {
+ // Send the IIS header
+ header('Refresh: 0;url=' . $url);
+ } else {
+ // Send generic header
+ header('Location: ' . $url);
+ }
+ exit();
+}
+
+// Removes all ctracker-related data from global space
+function unsetCtrackerData () {
+ // Debug message
+ //* DEBUG: */ error_log(__FUNCTION__ . ': CALLED!');
+
+ // Unset all ctracker data
+ foreach (array(
+ 'ctracker_base_path',
+ 'ctracker_host',
+ 'ctracker_dbname',
+ 'ctracker_user',
+ 'ctracker_password',
+ 'ctracker_debug_enabled',
+ 'ctracker_email',
+ 'ctracker_whitelist',
+ 'ctracker_get_blacklist',
+ 'ctracker_post_blacklist',
+ 'ctracker_header',
+ 'ctracker_post_track',
+ 'ctracker_checked_get',
+ 'ctracker_checked_post',
+ 'ctracker_checked_ua',
+ 'ctracker_last_sql',
+ 'ctracker_last_result',
+ 'ctracker_config',
+ 'ctracker_updates',
+ 'ctracker_language',
+ 'ctracker_localized',
+ 'ctracker_link',
+ 'ctracker_blocked_methods',
+ ) as $key) {
+ // Unset it
+ unset($GLOBALS[$key]);
+ } // END - foreach
+}
+
+// Sanitizes string
+function crackerTrackerSanitize ($str) {
+ return str_replace(array('//', '/./'), array('/', '/'), $str);
+}