OSDN Git Service

added NP_0TicketForPlugin code
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / globalfunctions.php
index abdaa3b..98598a5 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2006 The Nucleus Group
+ * Copyright (C) 2002-2007 The Nucleus Group
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  */
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2006 The Nucleus Group
-* @version $Id: globalfunctions.php,v 1.9 2006-08-31 21:00:21 kimitake Exp $
- * $NucleusJP: globalfunctions.php,v 1.8 2006/07/18 08:42:04 kimitake Exp $
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: globalfunctions.php,v 1.13 2007-02-06 09:00:24 kimitake Exp $
+ * $NucleusJP: globalfunctions.php,v 1.12 2007/02/04 06:28:46 kimitake Exp $
  */
 
 // needed if we include globalfunctions from install.php
 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
 
-$nucleus['version'] = 'v3.3SVN';
-$nucleus['codename'] = 'Lithium';
+//$nucleus['version'] = 'v3.3SVN';
+//$nucleus['codename'] = 'Lithium';
+$nucleus['version'] = 'v3.3';
+$nucleus['codename'] = '';
 
 checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES'));
 
@@ -85,6 +87,13 @@ if ($CONF['installscript'] != 1) { // vars were already included in install.php
        }
 }
 
+// sanitize option
+$bLoggingSanitizedResult=0;
+$bSanitizeAndContinue=0;
+
+$orgRequestURI = serverVar('REQUEST_URI');
+sanitizeParams();
+
 // get all variables that can come from the request and put them in the global scope
 $blogid        = requestVar('blogid');
 $itemid        = intRequestVar('itemid');
@@ -136,6 +145,18 @@ if ($CONF['UsingAdminArea']) {
 sql_connect();
 $SQLCount = 0;
 
+// logs sanitized result if need
+if ($orgRequestURI!==serverVar('REQUEST_URI')) {
+       $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
+       $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
+    if ($bLoggingSanitizedResult) {
+        addToLog(WARNING, $msg);
+    }
+    if (!$bSanitizeAndContinue) {
+        die("");
+    }
+}
+
 // makes sure database connection gets closed on script termination
 register_shutdown_function('sql_disconnect');
 
@@ -217,6 +238,7 @@ Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for det
 }
 
 // login completed
+ticketForPlugin();
 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
 
 // first, let's see if the site is disabled or not. always allow admin area access.
@@ -230,6 +252,7 @@ include($DIR_LIBS . 'PARSER.php');
 include($DIR_LIBS . 'SKIN.php');
 include($DIR_LIBS . 'TEMPLATE.php');
 include($DIR_LIBS . 'BLOG.php');
+include($DIR_LIBS . 'BODYACTIONS.php');
 include($DIR_LIBS . 'COMMENTS.php');
 include($DIR_LIBS . 'COMMENT.php');
 //include($DIR_LIBS . 'ITEM.php');
@@ -446,12 +469,26 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
 
                // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
                //       application/xhtml+xml seems to be working, so we're going to use it if we can.
+               //
+               // Note: reverted the following function in JP version
+               //
+       /*
+               // v3.3 code
                if (
                                ($contenttype == 'application/xhtml+xml')
                        &&      (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
                        ) {
                        $contenttype = 'text/html';
                }
+       */
+               // v3.2x code
+               if (
+                               ($contenttype == 'application/xhtml+xml')
+                       &&      (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
+                       )
+               {
+                       $contenttype = 'text/html';
+               }
 
                $manager->notify(
                        'PreSendContentType',
@@ -480,7 +517,8 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
 function startUpError($msg, $title) {
        ?>
        <html xmlns="http://www.w3.org/1999/xhtml">
-               <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title><?php echo htmlspecialchars($title)?></title></head>
+               <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+               <title><?php echo htmlspecialchars($title)?></title></head>
                <body>
                        <h1><?php echo htmlspecialchars($title)?></h1>
                        <?php echo $msg?>
@@ -593,7 +631,7 @@ function parseHighlight($query) {
   * Checks if email address is valid
   */
 function isValidMailAddress($address) {
-       if (preg_match('/^[a-zA-Z0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address) ) {
+       if (preg_match('/^[a-zA-Z+0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address)) {
                return 1;
        } else {
                return 0;
@@ -1400,6 +1438,305 @@ function checkVars($aVars) {
        }
 }
 
+
+/** 
+ * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
+ * to avoid XSS 
+ */
+function sanitizeParams()
+{
+       global $HTTP_SERVER_VARS;
+       
+       $array = array();
+       $str = '';
+       $frontParam = '';
+       
+       // REQUEST_URI of $HTTP_SERVER_VARS
+       $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
+       serverStringToArray($str, $array, $frontParam);
+       sanitizeArray($array);
+       arrayToServerString($array, $frontParam, $str);
+       
+       // QUERY_STRING of $HTTP_SERVER_VARS
+       $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
+       serverStringToArray($str, $array, $frontParam);
+       sanitizeArray($array);
+       arrayToServerString($array, $frontParam, $str);
+       
+       if (phpversion() >= '4.1.0') {
+               // REQUEST_URI of $_SERVER
+               $str =& $_SERVER["REQUEST_URI"];
+               serverStringToArray($str, $array, $frontParam);
+               sanitizeArray($array);
+               arrayToServerString($array, $frontParam, $str);
+       
+               // QUERY_STRING of $_SERVER
+               $str =& $_SERVER["QUERY_STRING"];
+               serverStringToArray($str, $array, $frontParam);
+               sanitizeArray($array);
+               arrayToServerString($array, $frontParam, $str);
+       }
+       
+       // $_GET
+       convArrayForSanitizing($_GET, $array);
+       sanitizeArray($array);
+       revertArrayForSanitizing($array, $_GET);
+       
+       // $_REQUEST (only GET param)
+       convArrayForSanitizing($_REQUEST, $array);
+       sanitizeArray($array);
+       revertArrayForSanitizing($array, $_REQUEST);
+}
+
+/** 
+ * Check ticket when not checked in plugin's admin page
+ * to avoid CSRF.
+ * Also avoid the access to plugin/index.php by guest user.
+ */
+function ticketForPlugin(){
+       global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
+       
+       /* initialize */
+       $ticketforplugin=array();
+       $ticketforplugin['ticket']=false;
+       
+       /* Check if using plugin's php file. */
+       if ($p_translated=serverVar('PATH_TRANSLATED')) {
+               if (!file_exists($p_translated)) $p_translated='';
+       }
+       if (!$p_translated) {
+               $p_translated=serverVar('SCRIPT_FILENAME');
+               if (!file_exists($p_translated)) {
+                       header("HTTP/1.0 404 Not Found");
+                       exit('');
+               }
+       }
+       $p_translated=str_replace('\\','/',$p_translated);
+       $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
+       if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.
+       
+       /* Solve the plugin php file or admin directory */
+       $phppath=substr($p_translated,strlen($d_plugins));
+       $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.
+       $path=preg_replace('/^NP_([.]*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
+       $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.
+       
+       /* Solve the plugin name. */
+       $plugins=array();
+       $query='SELECT pfile FROM '.sql_table('plugin');
+       $res=sql_query($query);
+       while($row=mysql_fetch_row($res)) {
+               $name=substr($row[0],3);
+               $plugins[strtolower($name)]=$name;
+       }
+       mysql_free_result($res);
+       if ($plugins[$path]) $plugin_name=$plugins[$path];
+       else if (array_key_exists($path,$plugins)) $plugin_name=$path;
+       else {
+               header("HTTP/1.0 404 Not Found");
+               exit('');
+       }
+       
+       /* Return if not index.php */
+       if ( $phppath!=strtolower($plugin_name).'/'
+               && $phppath!=strtolower($plugin_name).'/index.php' ) return;
+       
+       /* Exit if not logged in. */
+       if ( !$member->isLoggedIn() ) exit("You aren't logged in.");
+       
+       global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
+       
+       /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
+       if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');
+       if ($file=@file($p_translated)) {
+               $prevline='';
+               foreach($file as $line) {
+                       if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;
+                       $prevline=$line;
+               }
+       }
+       
+       /* Show a form if not valid ticket */
+       if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
+                       || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
+                               && (!$manager->checkTicket()) ){
+               if (!class_exists('PluginAdmin')) {
+                       $language = getLanguageName();
+                       include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
+                       include($DIR_LIBS . 'PLUGINADMIN.php');
+               }
+               $oPluginAdmin = new PluginAdmin($plugin_name);
+               $oPluginAdmin->start();
+               echo '<p>' . _ERROR_BADTICKET . "</p>\n";
+               
+               /* Show the form to confirm action */
+               // PHP 4.0.x support
+               $get=  (isset($_GET))  ? $_GET  : $HTTP_GET_VARS;
+               $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
+               // Resolve URI and QUERY_STRING
+               if ($uri=serverVar('REQUEST_URI')) {
+                       list($uri,$qstring)=explode('?',$uri);
+               } else {
+                       if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');
+                       $qstring=serverVar('QUERY_STRING');
+               }
+               if ($qstring) $qstring='?'.$qstring;
+               echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.
+                       htmlspecialchars($plugin_name)."</span> ?</p>\n";
+               switch(strtoupper(serverVar('REQUEST_METHOD'))){
+               case 'POST':
+                       echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
+                       $manager->addTicketHidden();
+                       _addInputTags($post);
+                       break;
+               case 'GET':
+                       echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
+                       $manager->addTicketHidden();
+                       _addInputTags($get);
+               default:
+                       break;
+               }
+               echo '<input type="submit" value="'._YES.'" />&nbsp;&nbsp;&nbsp;&nbsp;';
+               echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
+               echo "</form>\n";
+               
+               $oPluginAdmin->end();
+               exit;
+       }
+       
+       /* Create new ticket */
+       $ticket=$manager->addTicketToUrl('');
+       $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
+}
+function _addInputTags(&$keys,$prefix=''){
+       foreach($keys as $key=>$value){
+               if ($prefix) $key=$prefix.'['.$key.']';
+               if (is_array($value)) _addInputTags($value,$key);
+               else {
+                       if (get_magic_quotes_gpc()) $value=stripslashes($value);
+                       if ($key=='ticket') continue;
+                       echo '<input type="hidden" name="'.htmlspecialchars($key).
+                               '" value="'.htmlspecialchars($value).'" />'."\n";
+               }
+       }
+}
+
+/** 
+ * Convert the server string such as $_SERVER['REQUEST_URI']
+ * to arry like arry['blogid']=1 and array['page']=2 etc.
+ */
+function serverStringToArray($str, &$array, &$frontParam)
+{
+       // init param
+       $array = array();
+       $fronParam = "";
+
+       // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
+       if (strstr($str, "?")){
+               list($frontParam, $args) = preg_split("/\?/", $str, 2);
+       }
+       else {
+               $args = $str;
+               $frontParam = "";
+       }
+       
+       // If there is no args like blogid=1&page=2, return
+       if (!strstr($str, "=") && !strlen($frontParam)) {
+               $frontParam = $str;
+               return;
+       }
+
+       $array = explode("&", $args);
+}
+
+/** 
+ * Convert array like array['blogid'] to server string
+ * such as $_SERVER['REQUEST_URI']
+ */
+function arrayToServerString($array, $frontParam, &$str)
+{
+       if (strstr($str, "?")) {
+               $str = $frontParam . "?";
+       } else {
+               $str = $frontParam;
+       }
+       if (count($array)) {
+               $str .= implode("&", $array);
+       }
+}
+
+/** 
+ * Sanitize array parameters.
+ * This function checks both key and value.
+ * - check key if it inclues " (double quote),  remove from array
+ * - check value if it includes \ (escape sequece), remove remaining string
+ */
+function sanitizeArray(&$array)
+{      
+       $excludeListForSanitization = array('query');
+//     $excludeListForSanitization = array();
+
+       foreach ($array as $k => $v) {
+
+               // split to key and value
+               list($key, $val) = preg_split("/=/", $v, 2);
+               if (!isset($val)) {
+                       continue;
+               }
+
+               // when magic quotes is on, need to use stripslashes,
+               // and then addslashes
+               if (get_magic_quotes_gpc()) {
+                       $val = stripslashes($val);
+               }
+               $val = addslashes($val);
+               
+               // if $key is included in exclude list, skip this param
+               if (!in_array($key, $excludeListForSanitization)) {
+                               
+                       // check value
+                       list($val, $tmp) = explode('\\', $val);
+                       
+                       // remove control code etc.
+                       $val = strtr($val, "\0\r\n<>'\"", "       ");
+                               
+                       // check key
+                       if (preg_match('/\"/i', $key)) {
+                               unset($array[$k]);
+                               continue;
+                       }
+                               
+                       // set sanitized info
+                       $array[$k] = sprintf("%s=%s", $key, $val);
+               }
+       }
+}
+
+/**
+ * Convert array for sanitizeArray function
+ */
+function convArrayForSanitizing($src, &$array)
+{
+       $array = array();
+       foreach ($src as $key => $val) {
+               if (key_exists($key, $_GET)) {
+                       array_push($array, sprintf("%s=%s", $key, $val));
+               }
+       }
+}
+
+/**
+ * Revert array after sanitizeArray function
+ */
+function revertArrayForSanitizing($array, &$dst)
+{
+       foreach ($array as $v) {
+               list($key, $val) = preg_split("/=/", $v, 2);
+               $dst[$key] = $val;
+       }
+}
+
 /**
  * Stops processing the request and redirects to the given URL.
  * - no actual contents should have been sent to the output yet
@@ -1547,4 +1884,4 @@ function ifset(&$var) {
        return null;
 }
 
-?>
\ No newline at end of file
+?>