]> git.mxchange.org Git - ctracker.git/blob - libs/lib_general.php
1b2b886c4e3dfaacf8c7d0145ba9d54241b158fe
[ctracker.git] / libs / lib_general.php
1 <?php
2 /**
3  * General functions library
4  *
5  * @author              Roland Haeder <webmaster@shipsimu.org>
6  * @version             3.0.0
7  * @copyright   Copyright (c) 2009 - 2011 Cracker Tracker Team
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.shipsimu.org
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24
25 if (!function_exists('implode_r')) {
26         // Implode recursive a multi-dimension array, taken from www.php.net
27         function implode_r ($glue, $array, $array_name = NULL) {
28                 $return = array();
29                 while(list($key,$value) = @each($array)) {
30                         if(is_array($value)) {
31                                 // Is an array again, so call recursive
32                                 $return[] = implode_r($glue, $value, (string) $key);
33                         } else {
34                                 if($array_name != NULL) {
35                                         $return[] = $array_name . '[' . (string) $key . ']=' . $value . "\n";
36                                 } else {
37                                         $return[] = $key . '=' . $value."\n";
38                                 }
39                         }
40                 } // END - while
41
42                 // Return resulting array
43                 return(implode($glue, $return));
44         } // END - function
45 } // END - if
46
47 if (!function_exists('implode_secure')) {
48         // Implode a simple array with a 'call-back' to our escaper function
49         function implode_secure ($array) {
50                 // Return string
51                 $return = '';
52
53                 // Implode all data
54                 foreach ($array as $entry) {
55                         // Don't escape some
56                         if (in_array($entry, array('NOW()'))) {
57                                 // Add it with non-string glue
58                                 $return .= $entry . ',';
59                         } elseif (empty($entry)) {
60                                 // Empty strings need no escaping
61                                 $return .= '"",';
62                         } else {
63                                 // Secure this string and add it
64                                 $return .= '"' . crackerTrackerEscapeString($entry) . '",';
65                         }
66                 } // END - foreach
67
68                 // Remove last char
69                 $return = substr($return, 0, -1);
70
71                 // Return this string
72                 return $return;
73         } // END - function
74 } // END - if
75
76 // Load configuration, if found
77 function crackerTrackerLoadConfiguration () {
78         // FQFN
79         $fqfn = sprintf('%s/config/db_config.php', $GLOBALS['ctracker_base_path']);
80
81         // Is the file readable?
82         if (!isCrackerTrackerFileFound($fqfn)) {
83                 // No config file found
84                 die(__FUNCTION__.': No configuration file found.');
85         } // END - if
86
87         // Load it
88         require($fqfn);
89
90         // Load email header
91         $GLOBALS['ctracker_header'] = crackerTrackerLoadEmailTemplate('header');
92 }
93
94 // Getter for ctracker_debug_enabled
95 function isCrackerTrackerDebug () {
96         // Is it set?
97         $result = ((isset($GLOBALS['ctracker_debug_enabled'])) && ($GLOBALS['ctracker_debug_enabled'] === TRUE));
98
99         // Debug message
100         //* DEBUG: */ error_log('result=' . intval($result));
101
102         // Return it
103         return $result;
104 }
105
106 // Determines the real remote address
107 function determineCrackerTrackerRealRemoteAddress () {
108         // Initial value
109         $address = '0.0.0.0';
110
111         // Is a proxy in use?
112         if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
113                 // Proxy was used
114                 $address = trim($_SERVER['HTTP_X_FORWARDED_FOR']);
115         } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
116                 // Yet, another proxy
117                 $address = trim($_SERVER['HTTP_CLIENT_IP']);
118         } elseif (isset($_SERVER['REMOTE_ADDR'])) {
119                 // The regular address when no proxy was used
120                 $address = trim(getenv('REMOTE_ADDR'));
121         }
122
123         if ($address == 'unknown') {
124                 // Invalid IP somehow given
125                 $address = '0.0.0.0';
126         } elseif (strstr($address, ',')) {
127                 // This strips out the real address from proxy output
128                 $addressArray = explode(',', $address);
129                 $address = $addressArray[0];
130         }
131
132         // Return the result
133         return $address;
134 }
135
136 // Determine if a proxy was used
137 function isCrackerTrackerProxyUsed () {
138         // Check if specific entries are set
139         $proxyUsed = ((isset($_SERVER['HTTP_X_FORWARDED_FOR'])) || (isset($_SERVER['HTTP_CLIENT_IP'])));
140
141         // Return result
142         return $proxyUsed;
143 }
144
145 // Detects the user-agent string
146 function crackerTrackerUserAgent ($sanitize = FALSE) {
147         // Default is 'unknown'
148         $ua = 'unknown';
149
150         // Is the entry there?
151         if (isset($_SERVER['HTTP_USER_AGENT'])) {
152                 // Then use it securely
153                 $ua = crackerTrackerSecureString(urldecode($_SERVER['HTTP_USER_AGENT']));
154         } // END - if
155
156         // Sanitize it?
157         if ($sanitize === TRUE) {
158                 // Sanitize ...
159                 $ua = crackerTrackerSanitize($ua);
160         } // END - if
161
162         // Return it
163         return $ua;
164 }
165
166 // Detects the script name
167 function crackerTrackerScriptName ($sanitize = FALSE) {
168         // Default is NULL
169         $scriptName = NULL;
170
171         // Is it there?
172         if (!empty($_SERVER['SCRIPT_NAME'])) {
173                 // Return NULL
174                 $scriptName = crackerTrackerSecureString($_SERVER['SCRIPT_NAME']);
175         } // END - if
176
177         // Sanitize it?
178         if ($sanitize === TRUE) {
179                 // Sanitize ...
180                 $scriptName = crackerTrackerSanitize($scriptName);
181         } // END - if
182
183         // Return
184         return $scriptName;
185 }
186
187 // Detects the query string
188 function crackerTrackerQueryString ($sanitize = FALSE) {
189         // Default is NULL
190         $query = NULL;
191
192         // Is it there?
193         if (!empty($_SERVER['QUERY_STRING'])) {
194                 // Get string escaped
195                 $query = crackerTrackerEscapeString(urldecode($_SERVER['QUERY_STRING']));
196         } elseif (!empty($_SERVER['REQUEST_URI'])) {
197                 // Get string escaped
198                 $query = crackerTrackerEscapeString(urldecode($_SERVER['REQUEST_URI']));
199         }
200
201         // Sanitize it?
202         if ((!empty($query)) && ($sanitize === TRUE)) {
203                 // Sanitize ...
204                 $query = crackerTrackerSanitize($query);
205         } // END - if
206
207         // Return it
208         return $query;
209 }
210
211 // Detects the server's name
212 function crackerTrackerServerName ($sanitize = FALSE) {
213         // Default is NULL
214         $serverName = NULL;
215
216         // Is it there?
217         if (!empty($_SERVER['SERVER_NAME'])) {
218                 // Return NULL
219                 $serverName = crackerTrackerSecureString($_SERVER['SERVER_NAME']);
220         } // END - if
221
222         // Sanitize it?
223         if ($sanitize === TRUE) {
224                 // Sanitize ...
225                 $serverName = crackerTrackerSanitize($serverName);
226         } // END - if
227
228         // Return it
229         return $serverName;
230 }
231
232 // Detects the referer
233 function crackerTrackerReferer ($sanitize = FALSE) {
234         // Default is a dash
235         $referer = '-';
236
237         // Is it there?
238         if (!empty($_SERVER['HTTP_REFERER'])) {
239                 // Then use it securely
240                 $referer = crackerTrackerSecureString(urldecode($_SERVER['HTTP_REFERER']));
241         } // END - if
242
243         // Sanitize it?
244         if ($sanitize === TRUE) {
245                 // Sanitize ...
246                 $referer = crackerTrackerSanitize($referer);
247         } // END - if
248
249         // Return it
250         return $referer;
251 }
252
253 // Detects request method
254 function crackerTrackerRequestMethod () {
255         // Default is NULL
256         $method = NULL;
257
258         // Is it set?
259         if (!empty($_SERVER['REQUEST_METHOD'])) {
260                 // Then use it
261                 $method = $_SERVER['REQUEST_METHOD'];
262         } // END - if
263
264         // Return it
265         return $method;
266 }
267
268 // Detects the scripts path
269 function crackerTrackerScriptPath () {
270         // Should always be there!
271         $path = dirname(crackerTrackerScriptName()) . '/';
272
273         // Return detected path
274         return $path;
275 }
276
277 // Detects wether we have SSL
278 function crackerTrackerSecured () {
279         // Detect it
280         $ssl = ((isset($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off'));
281
282         // Return result
283         return $ssl;
284 }
285
286 // Secures a string by escaping it and passing it through strip_tags,htmlentities-chain
287 function crackerTrackerSecureString ($str) {
288         // First escape it
289         $str = crackerTrackerEscapeString($str);
290
291         // Then pass it through the functions
292         $str = htmlentities(strip_tags($str), ENT_QUOTES);
293
294         // Return it
295         return $str;
296 }
297
298 // Is the file there and readable?
299 function isCrackerTrackerFileFound ($FQFN) {
300         // Simply check it
301         return ((file_exists($FQFN)) && (is_readable($FQFN)));
302 }
303
304 // Loads a given "template" (this is more an include file)
305 function crackerTrackerLoadTemplate ($template) {
306         // Create the full-qualified filename (FQFN)
307         $FQFN = sprintf('%s/libs/templates/%s.tpl.php',
308                 $GLOBALS['ctracker_base_path'],
309                 $template
310         );
311
312         // Is this template found?
313         if (isCrackerTrackerFileFound($FQFN)) {
314                 // Detect language
315                 crackerTrackerLanguage();
316
317                 // Load it
318                 require_once($FQFN);
319         } else {
320                 // Not found, so die here
321                 crackerTrackerDie();
322         }
323 }
324
325 // Loads a given "template" (this is more an include file)
326 function crackerTrackerLoadLocalizedTemplate ($template) {
327         // Create the full-qualified filename (FQFN)
328         $FQFN = sprintf('%s/libs/templates/%s/%s.tpl.php',
329                 $GLOBALS['ctracker_base_path'],
330                 getCrackerTrackerLanguage(),
331                 $template
332         );
333
334         // Is this template found?
335         if (isCrackerTrackerFileFound($FQFN)) {
336                 // Load it
337                 require_once($FQFN);
338         } else {
339                 // Not found, so die here
340                 crackerTrackerDie();
341         }
342 }
343
344 // Detects the browser's language file and tries to load it, fall-back on english!
345 function crackerTrackerLanguage () {
346         // Default is English
347         $GLOBALS['ctracker_language'] = 'en';
348         $weight = 1;
349
350         // Is the language string there?
351         if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
352                 // Then detect it
353                 foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang) {
354                         // Split it again for q=x.x value
355                         $langArray = explode(';', $lang);
356
357                         // If there is an entry, we have a weight
358                         if ((isset($langArray[1])) && ($langArray[1] > $weight)) {
359                                 // Use this language/weight instead
360                                 $GLOBALS['ctracker_language'] = $langArray[0];
361                                 $weight   = $langArray[1];
362                         } // END - if
363                 } // END - foreach
364         } // END - if
365
366         // Construct FQFN
367         $FQFN = sprintf('%s/libs/language/%s.php',
368                 $GLOBALS['ctracker_base_path'],
369                 getCrackerTrackerLanguage()
370         );
371
372         // Is it not there, switch to "en"
373         if ((getCrackerTrackerLanguage() != 'en') && (!isCrackerTrackerFileFound($FQFN))) {
374                 // English is default!
375                 $GLOBALS['ctracker_language'] = 'en';
376
377                 // Construct FQFN again
378                 $FQFN = sprintf('%s/libs/language/en.php', $GLOBALS['ctracker_base_path']);
379         } // END - if
380
381         // Load the language file
382         require($FQFN);
383 }
384
385 // Loads a given email template and passes through $content
386 function crackerTrackerLoadEmailTemplate ($template, array $content = array(), $language = NULL) {
387         // Init language
388         crackerTrackerLanguage();
389
390         // Generate the FQFN
391         $FQFN = sprintf('%s/libs/mails/%s/%s.tpl',
392                 $GLOBALS['ctracker_base_path'],
393                 getCrackerTrackerLanguage($language),
394                 $template
395         );
396
397         // So is the file there?
398         if (isCrackerTrackerFileFound($FQFN)) {
399                 // Init result
400                 $result = 'No result from template ' . $template . '. Please report this at http://forum.shipsimu.org Thank you.';
401
402                 // Then load it
403                 //* DEBUG-DIE: */ die('<pre>$result = "' . crackerTrackerCompileCode(trim(file_get_contents($FQFN))) . '";</pre>');
404                 eval('$result = "' . crackerTrackerCompileCode(trim(file_get_contents($FQFN))) . '";');
405
406                 // Return the result
407                 return $result;
408         } else {
409                 // Not found
410                 crackerTrackerDie();
411         }
412 }
413
414 // Getter for message
415 function getCrackerTrackerLocalized ($message) {
416         // Default message
417         $output = '!' . $message . '!';
418
419         // Is the language string there?
420         if (isset($GLOBALS['ctracker_localized'][$message])) {
421                 // Use this instead
422                 $output = $GLOBALS['ctracker_localized'][$message];
423         } // END - if
424
425         // Return it
426         return $output;
427 }
428
429 // Tries to find a message and outputs it
430 function crackerTrackerOutputLocalized ($message) {
431         // Output it
432         print getCrackerTrackerLocalized($message);
433 }
434
435 // Compiles the given code
436 function crackerTrackerCompileCode ($code) {
437         // Find all $content[foo]
438         preg_match_all('/\$(content|GLOBALS)((\[([a-zA-Z0-9-_]+)\])*)/', $code, $matches);
439
440         // Replace " with {QUOTE}
441         $code = str_replace('"', '{QUOTE}', $code);
442
443         // Replace all
444         foreach ($matches[0] as $key=>$match) {
445                 // Replace it
446                 if (substr($match, 0, 8) == '$GLOBALS') {
447                         // $GLOBALS
448                         $code = str_replace($match, "\" . \$GLOBALS['" . $matches[4][$key] . "'] . \"", $code);
449                 } elseif (substr($match, 0, 8) == '$content') {
450                         // $content
451                         $code = str_replace($match, "\" . \$content['" . $matches[4][$key] . "'] . \"", $code);
452                 }
453         } // END - foreach
454
455         // Return it
456         return $code;
457 }
458
459 // "Getter" for language
460 function getCrackerTrackerLanguage ($lang = NULL) {
461         // Default is from browser
462         $language = $GLOBALS['ctracker_language'];
463
464         // Is $lang set?
465         if (!is_null($lang)) {
466                 // Then use this instead
467                 $language = $lang;
468         } // END - if
469
470         // Return it
471         return $language;
472 }
473
474 // "Getter" for ticket id
475 function getCrackerTrackerTicketId () {
476         // Default is zero
477         $id = 0;
478
479         // Is it set?
480         if (isset($GLOBALS['ctracker_last_ticket']['ctracker_ticket'])) {
481                 // Then use it
482                 $id = $GLOBALS['ctracker_last_ticket']['ctracker_ticket'];
483         } // END - if
484
485         // Return the number
486         return $id;
487 }
488
489 // Sends a cookie to the user that he would not see this security warning again
490 function sendCrackerTrackerCookie () {
491         // Set the cookie
492         // @TODO Why can't domain be set to value from crackerTrackerServerName() ?
493         setcookie('ctracker_ticket', getCrackerTrackerTicketId(), (time() + 60*60*24), '/', '', crackerTrackerSecured(), TRUE);
494         $_COOKIE['ctracker_ticket'] = getCrackerTrackerTicketId();
495 }
496
497 // Is the cookie set?
498 function ifCrackerTrackerCookieIsSet () {
499         // Is it set and valid?
500         return ((isset($_COOKIE['ctracker_ticket'])) && ($_COOKIE['ctracker_ticket'] > 0));
501 }
502
503 // Redirects to the same URL
504 function crackerTrackerRedirectSameUrl () {
505         // Construct the url
506         $url = '://' . crackerTrackerServerName() . crackerTrackerScriptName() . '?' . crackerTrackerQueryString();
507
508         // Do we have SSL?
509         if (crackerTrackerSecured()) {
510                 // HTTPS
511                 $url = 'https' . $url;
512         } else {
513                 // HTTP
514                 $url = 'http' . $url;
515         }
516
517         // And redirect
518         crackerTrackerSendRawRedirect($url);
519 }
520
521 /**
522  * Send a HTTP redirect to the browser. This function was taken from DokuWiki
523  * (GNU GPL 2; http://www.dokuwiki.org) and modified to fit into this script.
524  *
525  * Works arround Microsoft IIS cookie sending bug. Does exit the script.
526  *
527  * @link    http://support.microsoft.com/kb/q176113/
528  * @author  Andreas Gohr <andi@splitbrain.org>
529  * @access  private
530  */
531 function crackerTrackerSendRawRedirect ($url) {
532         // Better remove any data by ctracker
533         unsetCtrackerData();
534
535         // always close the session
536         session_write_close();
537
538         // Revert entity &amp;
539         $url = str_replace('&amp;', '&', $url);
540
541         // check if running on IIS < 6 with CGI-PHP
542         if ((isset($_SERVER['SERVER_SOFTWARE'])) && (isset($_SERVER['GATEWAY_INTERFACE'])) &&
543                 (strpos($_SERVER['GATEWAY_INTERFACE'],'CGI') !== FALSE) &&
544                 (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) &&
545                 ($matches[1] < 6)) {
546                 // Send the IIS header
547                 header('Refresh: 0;url=' . $url);
548         } else {
549                 // Send generic header
550                 header('Location: ' . $url);
551         }
552         exit();
553 }
554
555 // Removes all ctracker-related data from global space
556 function unsetCtrackerData () {
557         // Debug message
558         //* DEBUG: */ error_log(__FUNCTION__ . ': CALLED!');
559
560         // Unset all ctracker data
561         foreach (array(
562                         'ctracker_base_path',
563                         'ctracker_host',
564                         'ctracker_dbname',
565                         'ctracker_user',
566                         'ctracker_password',
567                         'ctracker_debug_enabled',
568                         'ctracker_email',
569                         'ctracker_whitelist',
570                         'ctracker_get_blacklist',
571                         'ctracker_post_blacklist',
572                         'ctracker_header',
573                         'ctracker_post_track',
574                         'ctracker_checked_get',
575                         'ctracker_checked_post',
576                         'ctracker_checked_ua',
577                         'ctracker_last_sql',
578                         'ctracker_last_result',
579                         'ctracker_config',
580                         'ctracker_updates',
581                         'ctracker_language',
582                         'ctracker_localized',
583                         'ctracker_link',
584                         'ctracker_blocked_requests',
585                 ) as $key) {
586                         // Unset it
587                         unset($GLOBALS[$key]);
588         } // END - foreach
589 }
590
591 // Sanitizes string
592 function crackerTrackerSanitize ($str) {
593         return str_replace(array('//', '/./'), array('/', '/'), $str);
594 }