3 // ----------------------------------------------------------------------
4 // PostNuke Content Management System
5 // Copyright (C) 2001 by the Post-Nuke Development Team.
6 // http://www.postnuke.com/
7 // ----------------------------------------------------------------------
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License (GPL)
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // To read the license please visit http://www.gnu.org/copyleft/gpl.html
21 // ----------------------------------------------------------------------
22 // Original Author of file: Jim McDonald
23 // Purpose of file: The PostNuke API
24 // ----------------------------------------------------------------------
32 /* Allows Postnuke to work with register_globals set to off
33 * Patch for php 4.2.x or greater
36 if (phpversion() >= "4.2.0") {
37 if (ini_get('register_globals') != 1) {
38 $supers = array('_REQUEST',
48 foreach ($supers as $__s) {
49 if ((isset($
$__s) == true) && (is_array($
$__s) == true)) {
50 extract($
$__s, EXTR_OVERWRITE
);
57 if (ini_get('register_globals') != 1) {
58 $supers = array('HTTP_POST_VARS',
67 foreach ($supers as $__s) {
68 if ((isset($
$__s) == true) && (is_array($
$__s) == true)) {
69 extract($
$__s, EXTR_OVERWRITE
);
86 define('_PNMODULE_STATE_UNINITIALISED', 1);
87 define('_PNMODULE_STATE_INACTIVE', 2);
88 define('_PNMODULE_STATE_ACTIVE', 3);
89 define('_PNMODULE_STATE_MISSING', 4);
90 define('_PNMODULE_STATE_UPGRADED', 5);
93 * 'All' and 'unregistered' for user and group permissions
95 define('_PNPERMS_ALL', '-1');
96 define('_PNPERMS_UNREGISTERED', '0');
99 * Core version informations - should be upgraded on each release for
100 * better control on config settings
102 define('_PN_VERSION_NUM', "0.7.2.6-Phoenix");
103 define('_PN_VERSION_ID', "PostNuke");
104 define('_PN_VERSION_SUB', "Phoenix");
107 * Fake module for config vars
109 define('_PN_CONFIG_MODULE', '/PNConfig');
118 * get all configuration variable into $pnconfig
119 * will be removed on .8
121 * @returns true|false
124 function pnConfigInit()
128 list($dbconn) = pnDBGetConn();
129 $pntable = pnDBGetTables();
131 $table = $pntable['module_vars'];
132 $columns = &$pntable['module_vars_column'];
137 $query = "SELECT $columns[name],
140 WHERE $columns[modname]='" . pnVarPrepForStore(_PN_CONFIG_MODULE
) . "'";
141 $dbresult = $dbconn->Execute($query);
142 if ($dbconn->ErrorNo() != 0) {
146 if ($dbresult->EOF
) {
151 while (!$dbresult->EOF
) {
152 list($k, $v) = $dbresult->fields
;
153 $dbresult->MoveNext();
154 if (($k != 'dbtype') && ($k != 'dbhost') && ($k != 'dbuname') && ($k != 'dbpass')
155 && ($k != 'dbname') && ($k != 'system') && ($k != 'prefix') && ($k != 'encoded')) {
156 $v =@unserialize
($v);
166 * get a configuration variable
167 * @param name the name of the variable
169 * @return value of the variable, or false on failure
171 function pnConfigGetVar($name)
174 if (isset($pnconfig[$name])) {
175 $result = $pnconfig[$name];
180 list($dbconn) = pnDBGetConn();
181 $pntable = pnDBGetTables();
183 $table = $pntable['module_vars'];
184 $columns = &$pntable['module_vars_column'];
189 $query = "SELECT $columns[value]
191 WHERE $columns[modname]='" . pnVarPrepForStore(_PN_CONFIG_MODULE
) . "'
192 AND $columns[name]='" . pnVarPrepForStore($name) . "'";
193 $dbresult = $dbconn->Execute($query);
196 * In any case of error return false
198 if ($dbconn->ErrorNo() != 0) {
202 if ($dbresult->EOF
) {
210 list ($result) = $dbresult->fields
;
211 $result = unserialize($result);
216 $pnconfig[$name] = $result;
228 * set a configuration variable
229 * @param name the name of the variable
230 * @param value the value of the variable
232 * @return true on success, false on failure
234 function pnConfigSetVar($name, $value)
237 * The database parameter are not allowed to change
239 if (empty($name) ||
($name == 'dbtype') ||
($name == 'dbhost') ||
($name == 'dbuname') ||
($name == 'dbpass')
240 ||
($name == 'dbname') ||
($name == 'system') ||
($name == 'prefix') ||
($name == 'encoded')) {
245 * Test on missing record
247 * Also solve SF-bug #580951
251 foreach ($pnconfig as $k => $v) {
253 * Test if the key name is in the array
259 $must_insert = false;
261 * Test on change. If not, just quit now
268 * End loop after success
277 list($dbconn) = pnDBGetConn();
278 $pntable = pnDBGetTables();
279 $table = $pntable['module_vars'];
280 $columns = &$pntable['module_vars_column'];
289 $query = "INSERT INTO $table
293 VALUES ('" . pnVarPrepForStore(_PN_CONFIG_MODULE
) . "',
294 '" . pnVarPrepForStore($name) . "',
295 '" . pnVarPrepForStore(serialize($value)). "')";
300 $query = "UPDATE $table
301 SET $columns[value]='" . pnVarPrepForStore(serialize($value)) . "'
302 WHERE $columns[modname]='" . pnVarPrepForStore(_PN_CONFIG_MODULE
) . "'
303 AND $columns[name]='" . pnVarPrepForStore($name) . "'";
306 $dbconn->Execute($query);
307 if ($dbconn->ErrorNo() != 0) {
314 $pnconfig[$name] = $value;
321 * delete a configuration variable
322 * @param name the name of the variable
324 * @return true on success, false on failure
326 function pnConfigDelVar($name)
334 // Don't allow deleting at current
339 * Initialise PostNuke
341 * Carries out a number of initialisation tasks to get PostNuke up and
347 // proper error_repoting
348 // e_all for development
349 // error_reporting(E_ALL);
350 // without warnings and notices for release
351 error_reporting(E_ALL
& ~E_NOTICE
& ~E_WARNING
& ~E_DEPRECATED
);
353 // Hack for some weird PHP systems that should have the
354 // LC_* constants defined, but don't
355 if (!defined('LC_TIME')) {
356 define('LC_TIME', 'LC_TIME');
359 // ADODB configuration
360 if (!defined('ADODB_DIR')) {
361 define('ADODB_DIR', dirname(__FILE__
) . '/../../../../vendor/adodb/adodb-php');
364 require ADODB_DIR
. '/adodb.inc.php';
366 // Temporary fix for hacking the hlpfile global
367 // TODO - remove with pre-0.71 code
371 // Initialise and load configuration
372 global $pnconfig, $pndebug;
374 include 'config.php';
378 // added this @define for .71, ugly ?
379 // i guess the E_ALL stuff.
380 @define
('WHERE_IS_PERSO', '');
382 // Initialise and load pntables
385 // if a multisite has its own pntables.
386 if (file_exists(WHERE_IS_PERSO
.'pntables.php')) {
387 include WHERE_IS_PERSO
.'pntables.php';
389 require 'pntables.php';
392 // Decode encoded DB parameters
393 if ($pnconfig['encoded']) {
394 $pnconfig['dbuname'] = base64_decode($pnconfig['dbuname']);
395 $pnconfig['dbpass'] = base64_decode($pnconfig['dbpass']);
396 $pnconfig['encoded'] = 0;
399 // Connect to database
401 die('Database initialisation failed');
404 // debugger if required
405 if ($pndebug['debug']) {
406 include_once 'includes/lensdebug.inc.php';
407 global $dbg, $debug_sqlcalls;
408 $dbg = new LensDebug();
412 // Build up old config array
415 // Set compression on if desired
417 if (pnConfigGetVar('UseCompression') == 1) {
418 ob_start("ob_gzhandler");
422 include 'includes/pnSession.php';
423 include 'includes/pnUser.php';
426 if (!pnSessionSetup()) {
427 die('Session setup failed');
430 if (!pnSessionInit()) {
431 die('Session initialisation failed');
434 include 'includes/security.php';
436 // See if a language update is required
437 $newlang = pnVarCleanFromInput('newlang');
438 if (!empty($newlang)) {
440 pnSessionSetVar('lang', $newlang);
442 $lang = pnSessionGetVar('lang');
445 // Load global language defines
446 if (isset($lang) && file_exists('language/' . pnVarPrepForOS($lang) . '/global.php')) {
447 $currentlang = $lang;
449 $currentlang = pnConfigGetVar('language');
450 pnSessionSetVar('lang', $currentlang);
453 include 'language/' . pnVarPrepForOS($currentlang) . '/global.php';
455 include 'modules/NS-Languages/api.php';
457 // Cross-Site Scripting attack defense - Sent by larsneo
458 // some syntax checking against injected javascript
460 $pnAntiCrackerMode = pnConfigGetVar('pnAntiCracker');
462 if ($pnAntiCrackerMode == 1) {
467 include 'includes/pnBanners.php';
469 // Other other includes
470 include 'includes/advblocks.php';
471 include 'includes/counter.php';
472 include 'includes/pnHTML.php';
473 include 'includes/pnMod.php';
474 include 'includes/queryutil.php';
475 include 'includes/xhtml.php';
476 include 'includes/oldfuncs.php';
479 if (pnConfigGetVar('httpref') == 1) {
480 include 'referer.php';
487 function pninclude_once($file)
494 // Get database parameters
496 $dbtype = $pnconfig['dbtype'];
497 $dbhost = $pnconfig['dbhost'];
498 $dbport = $pnconfig['dbport'];
499 $dbname = $pnconfig['dbname'];
500 $dbuname = $pnconfig['dbuname'];
501 $dbpass = $pnconfig['dbpass'];
503 // Database connection is a global (for now)
507 $dbconn = ADONewConnection($dbtype);
508 $dbconn->port
= $dbport;
509 $dbh = $dbconn->Connect($dbhost, $dbuname, $dbpass, $dbname);
512 //die("$dbtype://$dbuname:$dbpass@$dbhost/$dbname failed to connect" . $dbconn->ErrorMsg());
513 die("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n<title>PostNuke powered Website</title>\n</head>\n<body>\n<center>\n<h1>Problem in Database Connection</h1>\n<br /><br />\n<h5>This Website is powered by PostNuke</h5>\n<a href=\"http://www.postnuke.com\" target=\"_blank\"><img src=\"images/powered/postnuke.butn.gif\" border=\"0\" alt=\"Web site powered by PostNuke\" hspace=\"10\" /></a> <a href=\"http://php.weblogs.com/ADODB\" target=\"_blank\"><img src=\"images/powered/adodb2.gif\" alt=\"ADODB database library\" border=\"0\" hspace=\"10\" /></a><a href=\"http://www.php.net\" target=\"_blank\"><img src=\"images/powered/php2.gif\" alt=\"PHP Scripting Language\" border=\"0\" hspace=\"10\" /></a><br />\n<h5>Although this site is running the PostNuke software<br />it has no other connection to the PostNuke Developers.<br />Please refrain from sending messages about this site or its content<br />to the PostNuke team, the end will result in an ignored e-mail.</h5>\n</center>\n</body>\n</html>");
516 // Modified 5/2009 by BM for UTF-8 project
517 if ($pnconfig['utf8Flag']) {
518 $success_flag = $dbconn->Execute("SET NAMES 'utf8'");
519 if (!$success_flag) {
520 error_log("PHP custom error: from postnuke interface/main/calendar/includes/pnAPI.php - Unable to set up UTF8 encoding with mysql database", 0);
524 // ---------------------------------------
526 //Turn off STRICT SQL
527 $sql_strict_set_success = $dbconn->Execute("SET sql_mode = ''");
528 if (!$sql_strict_set_success) {
529 error_log("PHP custom error: from postnuke interface/main/calendar/includes/pnAPI.php - Unable to set strict sql setting", 0);
532 global $ADODB_FETCH_MODE;
533 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
535 // force oracle to a consistent date format for comparison methods later on
536 if (strcmp($dbtype, 'oci8') == 0) {
537 $dbconn->Execute("alter session set NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'");
540 // Sync MySQL time zone with PHP time zone.
541 $dbconn->Execute("SET time_zone = '" . (new DateTime())->format("P") . "'");
547 * get a list of database connections
549 * @return array of database connections
551 function pnDBGetConn()
555 return array($dbconn);
559 * get a list of database tables
561 * @return array of database tables
563 function pnDBGetTables()
573 * Gets a global variable, cleaning it up to try to ensure that
574 * hack attacks don't work
575 * @param var name of variable to get
577 * @returns string/array
578 * @return prepared variable if only one variable passed
579 * in, otherwise an array of prepared variables
581 function pnVarCleanFromInput()
583 $search = array('|</?\s*SCRIPT.*?>|si',
584 '|</?\s*FRAME.*?>|si',
585 '|</?\s*OBJECT.*?>|si',
586 '|</?\s*META.*?>|si',
587 '|</?\s*APPLET.*?>|si',
588 '|</?\s*LINK.*?>|si',
589 '|</?\s*IFRAME.*?>|si',
590 '|STYLE\s*=\s*"[^"]*"|si');
592 $replace = array('');
595 foreach (func_get_args() as $var) {
603 if (!isset($ourvar)) {
604 array_push($resarray, null);
608 if (empty($ourvar)) {
609 array_push($resarray, $ourvar);
613 if (!pnSecAuthAction(0, '::', '::', ACCESS_ADMIN
)) {
614 $ourvar = preg_replace($search, $replace, $ourvar);
617 // Add to result array
618 array_push($resarray, $ourvar);
622 if (func_num_args() == 1) {
632 * stripslashes on multidimensional arrays.
633 * Used in conjunction with pnVarCleanFromInput
635 * @param any variables or arrays to be stripslashed
637 function pnStripslashes(&$value)
639 if (!is_array($value)) {
640 $value = stripslashes($value);
642 array_walk($value, 'pnStripslashes');
649 * Gets a variable, cleaning it up such that the text is
650 * shown exactly as expected
651 * @param var variable to prepare
653 * @returns string/array
654 * @return prepared variable if only one variable passed
655 * in, otherwise an array of prepared variables
657 function pnVarPrepForDisplay()
659 // This search and replace finds the text 'x@y' and replaces
660 // it with HTML entities, this provides protection against
662 static $search = array('/(.)@(.)/s');
666 foreach (func_get_args() as $ourvar) {
668 $ourvar = htmlspecialchars($ourvar);
670 $ourvar = preg_replace_callback(
675 for ($i = 0; $i < (strlen($m[0])); $i++
) {
676 $output .= '&#' . ord($m[0][$i]) . ';';
686 array_push($resarray, $ourvar);
690 if (func_num_args() == 1) {
700 * Gets a variable, cleaning it up such that the text is
701 * shown exactly as expected, except for allowed HTML tags which
702 * are allowed through
703 * @param var variable to prepare
705 * @returns string/array
706 * @return prepared variable if only one variable passed
707 * in, otherwise an array of prepared variables
709 function pnVarPrepHTMLDisplay()
711 // This search and replace finds the text 'x@y' and replaces
712 // it with HTML entities, this provides protection against
715 // Note that the use of \024 and \022 are needed to ensure that
716 // this does not break HTML tags that might be around either
717 // the username or the domain name
718 static $search = array('/([^\024])@([^\022])/s');
722 if (!isset($allowedhtml)) {
723 $allowedhtml = array();
724 foreach (pnConfigGetVar('AllowableHTML') as $k => $v) {
729 $allowedhtml[] = "|<(/?$k)\s*/?>|i";
732 $allowedhtml[] = "|<(/?$k(\s+.*?)?)>|i";
739 foreach (func_get_args() as $ourvar) {
740 // Preparse var to mark the HTML that we want
741 $ourvar = preg_replace($allowedhtml, "\022\\1\024", $ourvar);
744 $ourvar = htmlspecialchars($ourvar);
745 $ourvar = preg_replace_callback(
747 function ($matches) {
749 sprintf("%03d", ord($matches[1])) .
751 sprintf("%03d", ord($matches[2])) . ";";
756 // Fix the HTML that we want
757 $ourvar = preg_replace_callback(
758 '/\022([^\024]*)\024/',
759 function ($matches) {
760 return '<' . strtr("$matches[1]", array('>' => '>', '<' => '<', '"' => '\"')) . '>';
765 // Fix entities if required
766 if (pnConfigGetVar('htmlentities')) {
767 $ourvar = preg_replace('/&([a-z#0-9]+);/i', "&\\1;", $ourvar);
771 array_push($resarray, $ourvar);
775 if (func_num_args() == 1) {
783 * ready databse output
785 * Gets a variable, cleaning it up such that the text is
786 * stored in a database exactly as expected
787 * @param var variable to prepare
789 * @returns string/array
790 * @return prepared variable if only one variable passed
791 * in, otherwise an array of prepared variables
793 function pnVarPrepForStore()
796 foreach (func_get_args() as $ourvar) {
798 if (!get_magic_quotes_runtime()) {
799 $ourvar = addslashes($ourvar);
803 array_push($resarray, $ourvar);
807 if (func_num_args() == 1) {
815 * ready operating system output
817 * Gets a variable, cleaning it up such that any attempts
818 * to access files outside of the scope of the PostNuke
819 * system is not allowed
820 * @param var variable to prepare
822 * @returns string/array
823 * @return prepared variable if only one variable passed
824 * in, otherwise an array of prepared variables
826 function pnVarPrepForOS()
828 static $search = array('!\.\./!si', // .. (directory traversal)
829 '!^.*://!si', // .*:// (start of URL)
830 '!/!si', // Forward slash (directory traversal)
831 '!\\\\!si'); // Backslash (directory traversal)
833 static $replace = array('',
839 foreach (func_get_args() as $ourvar) {
840 // Parse out bad things
841 $ourvar = preg_replace($search, $replace, $ourvar);
844 if (!get_magic_quotes_runtime()) {
845 $ourvar = addslashes($ourvar);
849 array_push($resarray, $ourvar);
853 if (func_num_args() == 1) {
861 * remove censored words
863 function pnVarCensor()
866 if (!isset($docensor)) {
867 $docensor = pnConfigGetVar('CensorMode');
870 static $search = array();
871 if (empty($search)) {
872 $repsearch = array('/o/i',
876 $repreplace = array('0',
880 $censoredwords = pnConfigGetVar('CensorList');
881 foreach ($censoredwords as $censoredword) {
883 $search[] = "/\b$censoredword\b/i";
885 // Common replacements
886 $mungedword = preg_replace($repsearch, $repreplace, $censoredword);
887 if ($mungedword != $censoredword) {
888 $search[] = "/\b$mungedword\b/";
893 $replace = pnConfigGetVar('CensorReplace');
896 foreach (func_get_args() as $ourvar) {
898 // Parse out nasty words
899 $ourvar = preg_replace($search, $replace, $ourvar);
903 array_push($resarray, $ourvar);
907 if (func_num_args() == 1) {
915 * validate a user variable
917 * @author Damien Bonvillain
918 * @author Gregor J. Rothfuss
919 * @since 1.23 - 2002/02/01
920 * @param var the variable to validate
921 * @param type the type of the validation to perform
922 * @param args optional array with validation-specific settings
924 * @return true if the validation was successful, false otherwise
926 function pnVarValidate($var, $type, $args = 0)
930 // all characters must be 7 bit ascii
931 $length = strlen($var);
940 $regexp = '/^(?:[^\s\000-\037\177\(\)<>@,;:\\"\[\]]\.?)+@(?:[^\s\000-\037\177\(\)<>@,;:\\\"\[\]]\.?)+\.[a-z]{2,6}$/Ui';
941 if (preg_match($regexp, $var)) {
949 // all characters must be 7 bit ascii
950 $length = strlen($var);
959 $regexp = '/^([!\$\046-\073=\077-\132_\141-\172~]|(?:%[a-f0-9]{2}))+$/i';
960 if (!preg_match($regexp, $var)) {
964 $url_array = @parse_url
($var);
965 if (empty($url_array)) {
968 return !empty($url_array['scheme']);
977 * Check an assertion to ensure that it is valid. If not, then die
978 * @param assertion the assertion
979 * @param filename the filename the assertion occurs in
980 * @param line the line number the assertion occurs in
982 function pnAssert($assertion, $file = 'Unknown', $line = 'Unknown', $msg = '')
988 // Assertion failed - log it
990 die("Assertion failed in $file at line $line - $msg");
992 die("Assertion failed in $file at line $line");
997 * get status message from previous operation
999 * Obtains any status message, and also destroys
1000 * it from the session to prevent duplication
1002 * @return the status message
1004 function pnGetStatusMsg()
1006 $msg = pnSessionGetVar('statusmsg');
1007 pnSessionDelVar('statusmsg');
1008 $errmsg = pnSessionGetVar('errormsg');
1009 pnSessionDelVar('errormsg');
1011 // Error message overrides status message
1012 if (!empty($errmsg)) {
1019 function pnThemeLoad($thistheme)
1027 // Lots of nasty globals for back-compatability with older themes
1036 global $postnuke_theme;
1039 // modification mouzaia .71
1041 // is this really useful ?
1042 /* $themefile = 'themes/' . pnVarPrepForOS(pnUserGetTheme()) . '/theme.php';
1043 if (!file_exists($themefile)) {
1047 // eugenio themeover 20020413
1048 if (@file
(WHERE_IS_PERSO
."themes/$thistheme/theme.php")) {
1049 include WHERE_IS_PERSO
."themes/$thistheme/theme.php";
1051 include "themes/$thistheme/theme.php";
1054 // end of modification
1059 function pnThemeGetVar($name)
1062 if (isset($
$name)) {
1068 * get base URI for PostNuke
1070 * @return base URI for PostNuke
1072 function pnGetBaseURI()
1074 global $HTTP_SERVER_VARS;
1076 // Get the name of this URI
1078 // Start of with REQUEST_URI
1079 if (isset($HTTP_SERVER_VARS['REQUEST_URI'])) {
1080 $path = $HTTP_SERVER_VARS['REQUEST_URI'];
1082 $path = getenv('REQUEST_URI');
1085 if ((empty($path)) ||
1086 (substr($path, -1, 1) == '/')) {
1087 // REQUEST_URI was empty or pointed to a path
1088 // Try looking at PATH_INFO
1089 $path = getenv('PATH_INFO');
1091 // No luck there either
1093 if (isset($HTTP_SERVER_VARS['SCRIPT_NAME'])) {
1094 $path = $HTTP_SERVER_VARS['SCRIPT_NAME'];
1096 $path = getenv('SCRIPT_NAME');
1101 $path = preg_replace('/[#\?].*/', '', $path);
1102 $path = dirname($path);
1104 if (preg_match('!^[/\\\]*$!', $path)) {
1112 * get base URL for PostNuke
1114 * @return base URL for PostNuke
1116 function pnGetBaseURL()
1118 global $HTTP_SERVER_VARS;
1120 if (empty($HTTP_SERVER_VARS['HTTP_HOST'])) {
1121 $server = getenv('HTTP_HOST');
1123 $server = $HTTP_SERVER_VARS['HTTP_HOST'];
1126 // IIS sets HTTPS=off
1127 if ((isset($HTTP_SERVER_VARS['HTTPS']) && $HTTP_SERVER_VARS['HTTPS'] != 'off') ||
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')) {
1128 $proto = 'https://';
1133 $path = pnGetBaseURI();
1135 return "$proto$server$path/";
1139 * Carry out a redirect
1140 * @param the URL to redirect to
1143 function pnRedirect($redirecturl)
1145 // Always close session before redirect
1146 if (function_exists('session_write_close')) {
1147 session_write_close();
1150 if (preg_match('!^http!', $redirecturl)) {
1151 // Absolute URL - simple redirect
1152 Header("Location: $redirecturl");
1155 // Removing leading slashes from redirect url
1156 $redirecturl = preg_replace('!^/*!', '', $redirecturl);
1159 $baseurl = pnGetBaseURL();
1161 Header("Location: $baseurl$redirecturl");
1166 * check to see if this is a local referral
1168 * @return true if locally referred, false if not
1170 function pnLocalReferer()
1172 global $HTTP_SERVER_VARS;
1174 if (empty($HTTP_SERVER_VARS['HTTP_HOST'])) {
1175 $server = getenv('HTTP_HOST');
1177 $server = $HTTP_SERVER_VARS['HTTP_HOST'];
1180 if (empty($HTTP_SERVER_VARS['HTTP_REFERER'])) {
1181 $referer = getenv('HTTP_REFERER');
1183 $referer = $HTTP_SERVER_VARS['HTTP_REFERER'];
1186 if (empty($referer) ||
preg_match("!^http://$server/!", $referer)) {
1193 // Hack - we need this for themes, but will get rid of it soon
1194 if (!function_exists('GetUserTime')) {
1195 function GetUserTime($time)
1197 if (pnUserLoggedIn()) {
1198 $time +
= (pnUserGetVar('timezone_offset') - pnConfigGetVar('timezone_offset')) * 3600;
1207 * @param to - recipient of the email
1208 * @param subject - title of the email
1209 * @param message - body of the email
1210 * @param headers - extra headers for the email
1211 * @param debug - if 1, echo mail content
1213 * @return true if the email was sent, false if not
1215 function pnMail($to, $subject, $message, $headers, $debug = 0)
1217 // Language translations
1218 switch (pnUserGetLang()) {
1220 if (!empty($headers)) {
1224 $headers .= "Content-Type: text/plain; charset=koi8-r";
1225 $subject = convert_cyr_string($subject, "w", "k");
1226 $message = convert_cyr_string($message, "w", "k");
1227 $headers = convert_cyr_string($headers, "w", "k");
1233 echo "Mail To: ".$to."<br>";
1234 echo "Mail Subject: ".$subject."<br>";
1235 echo "Mail Message: ".$message."<br>";
1236 echo "Mail Headers: ".$headers."<br>";
1240 // do not display error messages [class007]
1241 $return = @mail
($to, $subject, $message, $headers);
1245 /* Protects better diverse attempts of Cross-Site Scripting
1246 attacks, thanks to webmedic, Timax, larsneo.
1249 function pnSecureInput()
1252 /* Lets validate the current php version and set globals
1254 Do not change this value unless you know what you are
1255 doing you have been warned!
1258 //require('includes/htmlfilter.inc');
1260 if (phpversion() >= "4.2.0") {
1261 $HTTP_GET_VARS = $_GET;
1262 $HTTP_POST_VARS = $_POST;
1263 $HTTP_COOKIE_VARS = $_COOKIE;
1265 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;
1268 // Cross-Site Scripting attack defense - Sent by larsneo
1269 // some syntax checking against injected javascript
1272 if (count($HTTP_GET_VARS) > 0) {
1273 /* Lets now sanitize the GET vars
1277 foreach ($HTTP_GET_VARS as $secvalue) {
1278 if (!is_array($secvalue)) {
1279 if ((preg_match("/<[^>]*script*\"?[^>]*>/i", $secvalue)) ||
1280 (preg_match("/.*[[:space:]](or|and)[[:space:]].*(=|like).*/i", $secvalue)) ||
1281 (preg_match("/<[^>]*object*\"?[^>]*>/i", $secvalue)) ||
1282 (preg_match("/<[^>]*iframe*\"?[^>]*>/i", $secvalue)) ||
1283 (preg_match("/<[^>]*applet*\"?[^>]*>/i", $secvalue)) ||
1284 (preg_match("/<[^>]*meta*\"?[^>]*>/i", $secvalue)) ||
1285 (preg_match("/<[^>]*style*\"?[^>]*>/i", $secvalue)) ||
1286 (preg_match("/<[^>]*form*\"?[^>]*>/i", $secvalue)) ||
1287 (preg_match("/<[^>]*window.*\"?[^>]*>/i", $secvalue)) ||
1288 (preg_match("/<[^>]*alert*\"?[^>]*>/i", $secvalue)) ||
1289 (preg_match("/<[^>]*img*\"?[^>]*>/i", $secvalue)) ||
1290 (preg_match("/<[^>]*document.*\"?[^>]*>/i", $secvalue)) ||
1291 (preg_match("/<[^>]*cookie*\"?[^>]*>/i", $secvalue)) ||
1292 (preg_match("/\"/i", $secvalue))) {
1293 //pnMailHackAttempt(__FILE__,__LINE__,'pnSecurity Alert','Intrusion detection.');
1294 //Header("Location: index.php");
1300 /* Lets now sanitize the POST vars
1303 if (count($HTTP_POST_VARS) > 0) {
1304 foreach ($HTTP_POST_VARS as $secvalue) {
1305 if (!is_array($secvalue)) {
1306 if ((preg_match("/<[^>]*script*\"?[^>]*>/i", $secvalue)) ||
1307 (preg_match("/<[^>]*object*\"?[^>]*>/i", $secvalue)) ||
1308 (preg_match("/<[^>]*iframe*\"?[^>]*>/i", $secvalue)) ||
1309 (preg_match("/<[^>]*applet*\"?[^>]*>/i", $secvalue)) ||
1310 (preg_match("/<[^>]*window.*\"?[^>]*>/i", $secvalue)) ||
1311 (preg_match("/<[^>]*alert*\"?[^>]*>/i", $secvalue)) ||
1312 (preg_match("/<[^>]*document.*\"?[^>]*>/i", $secvalue)) ||
1313 (preg_match("/<[^>]*cookie*\"?[^>]*>/i", $secvalue)) ||
1314 (preg_match("/<[^>]*meta*\"?[^>]*>/i", $secvalue))
1316 //pnMailHackAttempt(__FILE__,__LINE__,'pnSecurity Alert','Intrusion detection.');
1317 //Header("Location: index.php");
1323 /* Lets now sanitize the COOKIE vars
1326 if (count($HTTP_COOKIE_VARS) > 0) {
1327 foreach ($HTTP_COOKIE_VARS as $secvalue) {
1328 if (!is_array($secvalue)) {
1329 if ((preg_match("/<[^>]*script*\"?[^>]*>/i", $secvalue)) ||
1330 (preg_match("/.*[[:space:]](or|and)[[:space:]].*(=|like).*/i", $secvalue)) ||
1331 (preg_match("/<[^>]*object*\"?[^>]*>/i", $secvalue)) ||
1332 (preg_match("/<[^>]*iframe*\"?[^>]*>/i", $secvalue)) ||
1333 (preg_match("/<[^>]*applet*\"?[^>]*>/i", $secvalue)) ||
1334 (preg_match("/<[^>]*meta*\"?[^>]*>/i", $secvalue)) ||
1335 (preg_match("/<[^>]*style*\"?[^>]*>/i", $secvalue)) ||
1336 (preg_match("/<[^>]*form*\"?[^>]*>/i", $secvalue)) ||
1337 (preg_match("/<[^>]*window.*\"?[^>]*>/i", $secvalue)) ||
1338 (preg_match("/<[^>]*alert*\"?[^>]*>/i", $secvalue)) ||
1339 (preg_match("/<[^>]*document.*\"?[^>]*>/i", $secvalue)) ||
1340 (preg_match("/<[^>]*cookie*\"?[^>]*>/i", $secvalue)) ||
1341 (preg_match("/<[^>]*img*\"?[^>]*>/i", $secvalue))
1343 pnMailHackAttempt(__FILE__
, __LINE__
, 'pnSecurity Alert', 'Intrusion detection.');
1344 //Header("Location: index.php");
1349 } # End of secure Input
1351 /* Function that compares the current php version on the
1352 system with the target one
1355 // Deprecate function reverting to php detecion function
1357 function pnPhpVersionCheck($vercheck)
1360 $minver = str_replace(".", "", $vercheck);
1361 $curver = str_replace(".", "", phpversion());
1363 if ($curver >= $minver) {
1370 function pnMailHackAttempt(
1371 $detecting_file = "(no filename available)",
1372 $detecting_line = "(no line number available)",
1373 $hack_type = "(no type given)",
1374 $message = "(no message given)"
1377 # Backwards compatibility fix with php 4.0.x and 4.1.x or greater Neo
1379 if (phpversion() >= "4.2.0") {
1389 global $HTTP_POST_VARS, $HTTP_GET_VARS, $HTTP_SERVER_VARS, $HTTP_ENV_VARS, $HTTP_COOKIE_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
1391 $_pv = $HTTP_POST_VARS;
1392 $_gv = $HTTP_GET_VARS;
1394 $_sv = $HTTP_SERVER_VARS;
1395 $_ev = $HTTP_ENV_VARS;
1396 $_cv = $HTTP_COOKIE_VARS;
1397 $_fv = $HTTP_POST_FILES;
1398 $_snv = $HTTP_SESSION_VARS;
1401 $output = "Attention site admin of ".pnConfigGetVar('sitename').",\n";
1402 $output .= "On ".ml_ftime(_DATEBRIEF
, ( GetUserTime(time()) ));
1403 $output .= " at ". ml_ftime(_TIMEBRIEF
, ( GetUserTime(time()) ));
1404 $output .= " the Postnuke code has detected that somebody tried to"
1405 ." send information to your site that may have been intended"
1406 ." as a hack. Do not panic, it may be harmless: maybe this"
1407 ." detection was triggered by something you did! Anyway, it"
1408 ." was detected and blocked. \n";
1409 $output .= "The suspicious activity was recognized in $detecting_file "
1410 ."on line $detecting_line, and is of the type $hack_type. \n";
1411 $output .= "Additional information given by the code which detected this: ".$message;
1412 $output .= "\n\nBelow you will find a lot of information obtained about "
1413 ."this attempt, that may help you to find what happened and "
1414 ."maybe who did it.\n\n";
1416 $output .= "\n=====================================\n";
1417 $output .= "Information about this user:\n";
1418 $output .= "=====================================\n";
1420 if (!pnUserLoggedIn()) {
1421 $output .= "This person is not logged in.\n";
1423 $output .= "Postnuke username: ".pnUserGetVar('uname') ."\n"
1424 ."Registered email of this Postnuke user: ". pnUserGetVar('email')."\n"
1425 ."Registered real name of this Postnuke user: ".pnUserGetVar('name') ."\n";
1428 $output .= "IP numbers: [note: when you are dealing with a real cracker "
1429 ."these IP numbers might not be from the actual computer he is "
1431 ."\n\t IP according to HTTP_CLIENT_IP: ".getenv('HTTP_CLIENT_IP')
1432 ."\n\t IP according to REMOTE_ADDR: ".getenv('REMOTE_ADDR')
1433 ."\n\t IP according to GetHostByName(\$REMOTE_ADDR): ".GetHostByName($REMOTE_ADDR)
1436 $output .= "\n=====================================\n";
1437 $output .= "Information in the \$_REQUEST array\n";
1438 $output .= "=====================================\n";
1440 while (list ( $key, $value ) = each($_rv)) {
1441 $output .= "REQUEST * $key : $value\n";
1444 $output .= "\n=====================================\n";
1445 $output .= "Information in the \$_GET array\n";
1446 $output .= "This is about variables that may have been ";
1447 $output .= "in the URL string or in a 'GET' type form.\n";
1448 $output .= "=====================================\n";
1450 while (list ( $key, $value ) = each($_gv)) {
1451 $output .= "GET * $key : $value\n";
1454 $output .= "\n=====================================\n";
1455 $output .= "Information in the \$_POST array\n";
1456 $output .= "This is about visible and invisible form elements.\n";
1457 $output .= "=====================================\n";
1459 while (list ( $key, $value ) = each($_pv)) {
1460 $output .= "POST * $key : $value\n";
1463 $output .= "\n=====================================\n";
1464 $output .= "Browser information\n";
1465 $output .= "=====================================\n";
1467 global $HTTP_USER_AGENT;
1468 $output .= "HTTP_USER_AGENT: ".$HTTP_USER_AGENT ."\n";
1470 $browser = (array) get_browser();
1471 while (list ( $key, $value ) = each($browser)) {
1472 $output .= "BROWSER * $key : $value\n";
1475 $output .= "\n=====================================\n";
1476 $output .= "Information in the \$_SERVER array\n";
1477 $output .= "=====================================\n";
1479 while (list ( $key, $value ) = each($_sv)) {
1480 $output .= "SERVER * $key : $value\n";
1483 $output .= "\n=====================================\n";
1484 $output .= "Information in the \$_ENV array\n";
1485 $output .= "=====================================\n";
1487 while (list ( $key, $value ) = each($_ev)) {
1488 $output .= "ENV * $key : $value\n";
1491 $output .= "\n=====================================\n";
1492 $output .= "Information in the \$_COOKIE array\n";
1493 $output .= "=====================================\n";
1495 while (list ( $key, $value ) = each($_cv)) {
1496 $output .= "COOKIE * $key : $value\n";
1499 $output .= "\n=====================================\n";
1500 $output .= "Information in the \$_FILES array\n";
1501 $output .= "=====================================\n";
1503 while (list ( $key, $value ) = each($_fv)) {
1504 $output .= "FILES * $key : $value\n";
1507 $output .= "\n=====================================\n";
1508 $output .= "Information in the \$_SESSION array\n";
1509 $output .= "This is session info. The variables\n";
1510 $output .= " starting with PNSV are PostNukeSessionVariables.\n";
1511 $output .= "=====================================\n";
1513 while (list ( $key, $value ) = each($_snv)) {
1514 $output .= "SESSION * $key : $value\n";
1517 $sitename = pnConfigGetVar('sitename');
1518 $adminmail = pnConfigGetVar('adminmail');
1520 $headers = "From: $sitename <$adminmail>\n"
1521 ."X-Priority: 1 (Highest)\n";
1523 pnMail($adminmail, 'Attempted hack on your site? (type: '.$hack_type.')', $output, $headers);