* @version 3.0.0 * @copyright Copyright (c) 2009 - 2017 Cracker Tracker Team * @license GNU GPL 3.0 or any newer version * @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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ 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)) { // Is an array again, so call recursive $return[] = implode_r($glue, $value, (string) $key); } else { 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)); } // 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) { // Return string $return = ''; // Implode all data foreach ($array as $entry) { // Don't escape some if (in_array($entry, array('NOW()'))) { // Add it with non-string glue $return .= $entry . ','; } elseif (empty($entry)) { // Empty strings need no escaping $return .= '"",'; } else { // Secure this string and add it $return .= '"' . crackerTrackerEscapeString($entry) . '",'; } } // END - foreach // Remove last char $return = substr($return, 0, -1); // Return this string return $return; } // END - function } // END - if // 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? $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 = array(), $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('
$result = "' . crackerTrackerCompileCode(trim(file_get_contents($FQFN))) . '";
'); 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); } /** * 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 * @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_requests', ) as $key) { // Unset it unset($GLOBALS[$key]); } // END - foreach } // Sanitizes string function crackerTrackerSanitize ($str) { return str_replace(array('//', '/./'), array('/', '/'), $str); }