国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

423 lines
13KB

  1. <?php
  2. @set_time_limit(0);
  3. /**
  4. * 系统运行环境检测
  5. *
  6. * @version $Id: testenv.php 13:57 2011/11/10 tianya $
  7. * @package DedeCMS.Administrator
  8. * @copyright Copyright (c) 2020, DedeBIZ.COM
  9. * @license https://www.dedebiz.com/license
  10. * @link https://www.dedebiz.com
  11. */
  12. require_once(dirname(__FILE__)."/config.php");
  13. CheckPurview('sys_Edit');
  14. $action = isset($action)? $action : '';
  15. ?>
  16. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  17. <html xmlns="http://www.w3.org/1999/xhtml">
  18. <head>
  19. <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $GLOBALS['cfg_soft_lang']; ?>">
  20. <title>系统运行目录权限检测</title>
  21. <link rel="stylesheet" type="text/css" href="css/base.css" />
  22. <link rel="stylesheet" type="text/css" href="css/indexbody.css" />
  23. <script type="text/javascript" src="../static/js/jquery.js" ></script>
  24. </head>
  25. <body leftmargin="8" topmargin='8' bgcolor="#FFFFFF" style="min-width:840px">
  26. <?php
  27. if(!function_exists('TestWriteable'))
  28. {
  29. // 检测是否可写
  30. function TestWriteable($d, $c=TRUE)
  31. {
  32. $tfile = '_write_able.txt';
  33. $d = preg_replace("/\/$/", '', $d);
  34. $fp = @fopen($d.'/'.$tfile,'w');
  35. if(!$fp)
  36. {
  37. if( $c==false )
  38. {
  39. @chmod($d, 0777);
  40. return false;
  41. }
  42. else return TestWriteable($d, true);
  43. }
  44. else
  45. {
  46. fclose($fp);
  47. return @unlink($d.'/'.$tfile) ? true : false;
  48. }
  49. }
  50. }
  51. if(!function_exists('TestExecuteable'))
  52. {
  53. // 检查是否具目录可执行
  54. function TestExecuteable($d='.', $siteuRL='', $rootDir='') {
  55. $testStr = '<'.chr(0x3F).'p'.chr(hexdec(68)).chr(112)."\n\r";
  56. $filename = md5($d).'.php';
  57. $testStr .= 'function test(){ echo md5(\''.$d.'\');}'."\n\rtest();\n\r";
  58. $testStr .= chr(0x3F).'>';
  59. $reval = false;
  60. if(empty($rootDir)) $rootDir = DEDEROOT;
  61. if (TestWriteable($d))
  62. {
  63. @file_put_contents($d.'/'.$filename, $testStr);
  64. $remoteUrl = $siteuRL.'/'.str_replace($rootDir, '', str_replace("\\", '/',realpath($d))).'/'.$filename;
  65. $tempStr = @PostHost($remoteUrl);
  66. $reval = (md5($d) == trim($tempStr))? true : false;
  67. unlink($d.'/'.$filename);
  68. return $reval;
  69. } else
  70. {
  71. return -1;
  72. }
  73. }
  74. }
  75. if(!function_exists('PostHost'))
  76. {
  77. function PostHost($host,$data='',$method='GET',$showagent=null,$port=null,$timeout=30){
  78. $parse = @parse_url($host);
  79. if (empty($parse)) return false;
  80. if ((int)$port>0) {
  81. $parse['port'] = $port;
  82. } elseif (!@$parse['port']) {
  83. $parse['port'] = '80';
  84. }
  85. $parse['host'] = str_replace(array('http://','https://'),array('','ssl://'),"$parse[scheme]://").$parse['host'];
  86. if (!$fp=@fsockopen($parse['host'],$parse['port'],$errnum,$errstr,$timeout)) {
  87. return false;
  88. }
  89. $method = strtoupper($method);
  90. $wlength = $wdata = $responseText = '';
  91. $parse['path'] = str_replace(array('\\','//'),'/',@$parse['path'])."?".@$parse['query'];
  92. if ($method=='GET') {
  93. $separator = @$parse['query'] ? '&' : '';
  94. substr($data,0,1)=='&' && $data = substr($data,1);
  95. $parse['path'] .= $separator.$data;
  96. } elseif ($method=='POST') {
  97. $wlength = "Content-length: ".strlen($data)."\r\n";
  98. $wdata = $data;
  99. }
  100. $write = "$method $parse[path] HTTP/1.0\r\nHost: $parse[host]\r\nContent-type: application/x-www-form-urlencoded\r\n{$wlength}Connection: close\r\n\r\n$wdata";
  101. @fwrite($fp,$write);
  102. while ($data = @fread($fp, 4096)) {
  103. $responseText .= $data;
  104. }
  105. @fclose($fp);
  106. empty($showagent) && $responseText = trim(stristr($responseText,"\r\n\r\n"),"\r\n");
  107. return $responseText;
  108. }
  109. }
  110. $allPath = array();
  111. $needDir = "$cfg_medias_dir|
  112. $cfg_image_dir|
  113. $ddcfg_image_dir|
  114. $cfg_user_dir|
  115. $cfg_soft_dir|
  116. $cfg_other_medias|
  117. $cfg_medias_dir/flink|
  118. $cfg_cmspath/data|
  119. $cfg_cmspath/data/$cfg_backup_dir|
  120. $cfg_cmspath/data/textdata|
  121. $cfg_cmspath/data/sessions|
  122. $cfg_cmspath/data/tplcache|
  123. $cfg_cmspath/data/admin|
  124. $cfg_cmspath/data/enums|
  125. $cfg_cmspath/data/mark|
  126. $cfg_cmspath/data/module|
  127. $cfg_cmspath/data/rss|
  128. $cfg_special|
  129. $cfg_cmspath$cfg_arcdir";
  130. $needDir = explode('|', $needDir);
  131. foreach($needDir as $key => $val)
  132. {
  133. $allPath[trim($val)] = array(
  134. 'read'=>true, // 读取
  135. 'write'=>true, // 写入
  136. 'execute'=>false // 执行
  137. );
  138. }
  139. // 所有栏目目录
  140. $sql = "SELECT typedir FROM #@__arctype ORDER BY id DESC";
  141. $dsql->SetQuery($sql);
  142. $dsql->Execute('al', $sql);
  143. while($row = $dsql->GetArray('al'))
  144. {
  145. $typedir = str_replace($cfg_basehost, '', $row['typedir']);
  146. if(preg_match("/^http:|^ftp:/i", $row['typedir'])) continue;
  147. $typedir = str_replace("{cmspath}", $cfg_cmspath, $row['typedir']);
  148. $allPath[trim($typedir)] = array(
  149. 'read'=>true, // 读取
  150. 'write'=>true, // 写入
  151. 'execute'=>false // 执行
  152. );
  153. }
  154. // 只允许读取,不允许写入的目录
  155. $needDir = array(
  156. 'include',
  157. 'member',
  158. 'plus',
  159. );
  160. // 获取子目录
  161. function GetSondir($d, &$dirname=array())
  162. {
  163. $dh = dir($d);
  164. while($filename = $dh->read() )
  165. {
  166. if(substr($filename, 0, 1)=='.' || is_file($d.'/'.$filename) ||
  167. preg_match("#^(svn|bak-)#i", $filename) )
  168. {
  169. CONTINUE;
  170. }
  171. if(is_dir($d.'/'.$filename))
  172. {
  173. $dirname[] = $d.'/'.$filename;
  174. GetSondir($d.'/'.$filename,$dirname);
  175. }
  176. }
  177. $dh->close();
  178. return $dirname;
  179. }
  180. //获取所有文件列表
  181. function preg_ls($path=".", $rec=FALSE, $pat="/.*/", $ignoredir='')
  182. {
  183. while (substr ($path,-1,1) =="/")
  184. {
  185. $path=substr ($path,0,-1);
  186. }
  187. if (!is_dir ($path) )
  188. {
  189. $path=dirname ($path);
  190. }
  191. if ($rec!==TRUE)
  192. {
  193. $rec=FALSE;
  194. }
  195. $d=dir ($path);
  196. $ret=Array ();
  197. while (FALSE!== ($e=$d->read () ) )
  198. {
  199. if ( ($e==".") || ($e=="..") )
  200. {
  201. continue;
  202. }
  203. if ($rec && is_dir ($path."/".$e) && ($ignoredir == '' || strpos($ignoredir,$e ) === FALSE))
  204. {
  205. $ret = array_merge ($ret, preg_ls($path."/".$e, $rec, $pat, $ignoredir));
  206. continue;
  207. }
  208. if (!preg_match ($pat, $e) )
  209. {
  210. continue;
  211. }
  212. $ret[] = $path."/".$e;
  213. }
  214. return (empty ($ret) && preg_match ($pat,basename($path))) ? Array ($path."/") : $ret;
  215. }
  216. foreach($needDir as $key => $val)
  217. {
  218. $allPath[trim('/'.$val)] = array(
  219. 'read'=>true, // 读取
  220. 'write'=>false, // 写入
  221. 'execute'=>true // 执行
  222. );
  223. $sonDir = GetSondir(DEDEROOT.'/'.$val);
  224. foreach($sonDir as $kk => $vv)
  225. {
  226. $vv = trim(str_replace(DEDEROOT, '', $vv));
  227. $allPath[$vv] = array(
  228. 'read'=>true, // 读取
  229. 'write'=>false, // 写入
  230. 'execute'=>true // 执行
  231. );
  232. }
  233. }
  234. // 不需要执行的
  235. $needDir = array(
  236. '/images',
  237. '/templets'
  238. );
  239. foreach($needDir as $key => $val)
  240. {
  241. $allPath[trim('/'.$val)] = array(
  242. 'read'=>true, // 读取
  243. 'write'=>false, // 写入
  244. 'execute'=>false // 执行
  245. );
  246. $sonDir = GetSondir(DEDEROOT.'/'.$val);
  247. foreach($sonDir as $kk => $vv)
  248. {
  249. $vv = trim(str_replace(DEDEROOT.'/', '', $vv));
  250. $allPath[$vv] = array(
  251. 'read'=>true, // 读取
  252. 'write'=>false, // 写入
  253. 'execute'=>false // 执行
  254. );
  255. }
  256. }
  257. // 所有js建议只读
  258. $jsDir = array(
  259. '/images',
  260. '/templets',
  261. '/include'
  262. );
  263. foreach ($jsDir as $k => $v)
  264. {
  265. $jsfiles = preg_ls(DEDEROOT.$v, TRUE, "/.*\.(js)$/i");
  266. foreach ($jsfiles as $k => $v)
  267. {
  268. $vv = trim(str_replace(DEDEROOT.'/', '/', $v));
  269. $allPath[$vv] = array(
  270. 'read'=>true, // 读取
  271. 'write'=>false, // 写入
  272. 'execute'=>false // 执行
  273. );
  274. }
  275. }
  276. ?>
  277. <div id="safemsg">
  278. <dl style="margin-left:0.5%;margin-right:0.5%; width:97%" id="item1" class="dbox">
  279. <dt class="lside"><span class="l" style="float:left">系统运行目录权限检测</span><span style="float:right; margin-right:20px"><a href="index_body.php">返回主页</a></span><span style="float:right; margin-right:20px"><a href="http://help.dedecms.com/install-use/apply/2011/1111/2131.html" target="_blank">帮助说明</a></span></dt>
  280. <dd>
  281. <div style="padding:10px"> 说明:本程序用于检测DedeCMS站点所涉及的目录权限,并且提供一个全面的检测说明,您可以根据检测报告来配置站点以保证站点更为安全。</div>
  282. <div id="tableHeader" style="margin-left:10px">
  283. <table width="784" border="0" cellpadding="0" cellspacing="1" bgcolor="#047700" id="scanTable">
  284. <thead>
  285. <tr>
  286. <td width="40%" height="25" align="center" bgcolor="#E3F1D1">目录</td>
  287. <td width="20%" height="25" align="center" bgcolor="#E3F1D1">执行</td>
  288. <td width="20%" height="25" align="center" bgcolor="#E3F1D1">读取</td>
  289. <td width="20%" height="25" align="center" bgcolor="#E3F1D1">写入</td>
  290. </tr>
  291. </thead>
  292. </table>
  293. </div>
  294. <div id="safelist" style="margin-left:10px">
  295. <div class="install" id="log" style="height: 260px; overflow: auto;">
  296. <table width="784" border="0" cellpadding="0" cellspacing="1" bgcolor="#047700" id="scanTable">
  297. <tbody id="mainList">
  298. </tbody>
  299. </table>
  300. </div>
  301. </div>
  302. </dd>
  303. </dl>
  304. </div>
  305. <div style="margin: 0 auto; width:200px"><a href="javascript:startScan();"><img src="images/btn_scan.gif" width="154" height="46" /></a></div>
  306. <script type="text/javascript">
  307. $ = jQuery;
  308. var log = "<?php
  309. foreach($allPath as $key => $val)
  310. {
  311. if(is_dir(DEDEROOT.$key))
  312. {
  313. ?><?php echo $key;?>|<?php
  314. $rs = TestExecuteable(DEDEROOT.$key, $cfg_basehost, $cfg_cmspath);
  315. if($rs === -1)
  316. {
  317. echo "<font color='red'>无法判断</font>";
  318. } else {
  319. if($val['execute'] == true)
  320. echo $rs != $val['execute']? "<font color='red'>错误(不可执行)</font>" : "<font color='green'>正常(可执行)</font>";
  321. else
  322. echo $rs != $val['execute']? "<font color='red'>错误(可执行)</font>" : "<font color='green'>正常(不可执行)</font>";
  323. }
  324. ?>|<?php
  325. if($val['read'] == true)
  326. echo is_readable(DEDEROOT.$key) != $val['read']? "<font color='red'>错误(不可读)</font>" : "<font color='green'>正常(可读)</font>";
  327. else
  328. echo is_readable(DEDEROOT.$key) != $val['read']? "<font color='red'>错误(可读)</font>" : "<font color='green'>正常(不可读)</font>";
  329. ?>|<?php
  330. if($val['write'] == true)
  331. echo TestWriteable(DEDEROOT.$key) != $val['write']? "<font color='red'>错误(不可写)</font>" : "<font color='green'>正常(可写)</font>";
  332. else
  333. echo TestWriteable(DEDEROOT.$key) != $val['write']? "<font color='red'>错误(可写)</font>" : "<font color='green'>正常(不可写)</font>";
  334. ?><dedecms><?php
  335. } else {
  336. ?><?php echo $key;?>|无需判断|<?php
  337. if($val['read'] == true)
  338. echo is_readable(DEDEROOT.$key) != $val['read']? "<font color='red'>错误(不可读)</font>" : "<font color='green'>正常(可读)</font>";
  339. else
  340. echo is_readable(DEDEROOT.$key) != $val['read']? "<font color='red'>错误(可读)</font>" : "<font color='green'>正常(不可读)</font>";
  341. ?>|<?php
  342. if($val['write'] == true)
  343. echo is_writable(DEDEROOT.$key) != $val['write']? "<font color='red'>错误(不可写)</font>" : "<font color='green'>正常(可写)</font>";
  344. else
  345. echo is_writable(DEDEROOT.$key) != $val['write']? "<font color='red'>错误(可写)</font>" : "<font color='green'>正常(不可写)</font>";
  346. ?><dedecms><?php
  347. }
  348. }
  349. ?>";
  350. var n = 0;
  351. var timer = 0;
  352. log = log.split('<dedecms>');
  353. function GoPlay(){
  354. if (n > log.length-1) {
  355. n=-1;
  356. clearIntervals();
  357. }
  358. if (n > -1) {
  359. postcheck(n);
  360. n++;
  361. }
  362. }
  363. function postcheck(n){
  364. var item = log[n];
  365. item = item.split('|');
  366. document.getElementById('log').scrollTop = document.getElementById('log').scrollHeight;
  367. if(item == ''){return false;}
  368. var tempvar='<tr>\r <td width="40%" height="23" bgcolor="#FFFFFF">'+item[0]+'</td>\r <td width="20%" height="23" align="center" bgcolor="#FEF7C5">'+item[1]+'</td>\r <td width="20%" height="23" align="center" bgcolor="#FFFFFF">\r '+item[2]+'</td>\r <td width="20%" height="23" align="center" bgcolor="#FFFFFF">\r '+item[3]+'</td>\r </tr> ';
  369. //chiledelem.innerHTML = tempvar;
  370. //document.getElementById("mainList").appendChild(chiledelem);
  371. $("#mainList").append(tempvar);
  372. document.getElementById('log').scrollTop = document.getElementById('log').scrollHeight;
  373. }
  374. function setIntervals(){
  375. timer = setInterval('GoPlay()',50);
  376. }
  377. function clearIntervals(){
  378. clearInterval(timer);
  379. //document.getElementById('install').submit();
  380. alert('全部检测完毕,您可以按照检测结果进行系统权限调整!');
  381. }
  382. //setTimeout(setIntervals, 100);
  383. function changeHeight()
  384. {
  385. var newheight = $(window).height() - 170;
  386. $("#safelist").css('height', newheight + 'px');
  387. var logheight = newheight;
  388. $("#log").css('height', logheight + 'px');
  389. }
  390. // 开始检测
  391. function startScan()
  392. {
  393. setTimeout(setIntervals, 100);
  394. }
  395. $.ready = function(){
  396. changeHeight();
  397. $(window).resize(function()
  398. {
  399. changeHeight();
  400. });
  401. };
  402. </script>
  403. </body>