PageRenderTime 71ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/system/modules/blacklist/mcp.blacklist.php

https://github.com/danboy/Croissierd
PHP | 1334 lines | 865 code | 282 blank | 187 comment | 137 complexity | 88634fec3b859627baef70a5edace9d2 MD5 | raw file
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010 EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/docs/license.html
  13. =====================================================
  14. File: mcp.blacklist.php
  15. -----------------------------------------------------
  16. Purpose: Blacklist class - CP
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Blacklist_CP {
  24. var $version = '2.0';
  25. var $value = '';
  26. var $LB = "\r\n";
  27. /** -------------------------
  28. /** Constructor
  29. /** -------------------------*/
  30. function Blacklist_CP( $switch = TRUE )
  31. {
  32. global $IN, $DB;
  33. /** -------------------------------
  34. /** Is the module installed?
  35. /** -------------------------------*/
  36. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_modules WHERE module_name = 'Blacklist'");
  37. if ($query->row['count'] == 0)
  38. {
  39. return;
  40. }
  41. /** -------------------------
  42. /** Updates
  43. /** -------------------------*/
  44. $query = $DB->query("SELECT module_version FROM exp_modules WHERE module_name = 'Blacklist'");
  45. if ($query->num_rows > 0)
  46. {
  47. $sql = array();
  48. if ( ! $DB->table_exists('exp_whitelisted'))
  49. {
  50. $sql[] = "CREATE TABLE IF NOT EXISTS `exp_whitelisted` (
  51. `whitelisted_type` VARCHAR( 20 ) NOT NULL ,
  52. `whitelisted_value` TEXT NOT NULL);";
  53. }
  54. foreach($sql as $query)
  55. {
  56. $DB->query($query);
  57. }
  58. }
  59. /** -------------------------
  60. /** Menu Switch
  61. /** -------------------------*/
  62. if ($switch)
  63. {
  64. switch($IN->GBL('P'))
  65. {
  66. case 'pmachine_blacklist' : $this->pmachine_blacklist();
  67. break;
  68. case 'pmachine_whitelist' : $this->pmachine_whitelist();
  69. break;
  70. case 'view_blacklist' : $this->view_blacklist();
  71. break;
  72. case 'update_blacklist' : $this->update_blacklist();
  73. break;
  74. case 'view_whitelist' : $this->view_whitelist();
  75. break;
  76. case 'update_whitelist' : $this->update_whitelist();
  77. break;
  78. case 'write_htaccess' : $this->write_htaccess();
  79. break;
  80. default : $this->blacklist_home();
  81. break;
  82. }
  83. }
  84. }
  85. /* END */
  86. /** -------------------------
  87. /** Blacklist Home Page
  88. /** -------------------------*/
  89. function blacklist_home($message='')
  90. {
  91. global $DSP, $DB, $LANG, $PREFS, $SESS;
  92. $DSP->title = $LANG->line('blacklist_module_name');
  93. $DSP->crumb = $LANG->line('blacklist_module_name');
  94. // Blacklist
  95. if ($message != '')
  96. {
  97. $DSP->body .= $DSP->qdiv('successBox', $DSP->qdiv('success', $message));
  98. }
  99. $DSP->body .= $DSP->table('tableBorder', '0', '0', '100%').
  100. $DSP->tr();
  101. $DSP->body .= $DSP->td('tableHeading', '', '2');
  102. $DSP->body .= $LANG->line('blacklist_module_name');
  103. $DSP->body .= $DSP->td_c();
  104. $DSP->body .= $DSP->tr_c();
  105. $DSP->body .= $DSP->tr();
  106. $DSP->body .= $DSP->td('tableCellTwo', '40%');
  107. $DSP->body .= $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist'.AMP.'P=view_blacklist', $LANG->line('ref_view_blacklist')));
  108. $DSP->body .= $DSP->td_c();
  109. $DSP->body .= $DSP->td('tableCellTwo', '60%');
  110. if ($license = $PREFS->ini('license_number'))
  111. {
  112. $DSP->body .= $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist'.AMP.'P=pmachine_blacklist', $LANG->line('pmachine_blacklist'));
  113. }
  114. else
  115. {
  116. $DSP->body .= $DSP->qdiv('defaultBold', $LANG->line('pmachine_blacklist')).$DSP->qdiv('itemWrapper', $DSP->qdiv('highlight', $LANG->line('requires_license_number')));
  117. }
  118. $DSP->body .= $DSP->td_c();
  119. $DSP->body .= $DSP->tr_c();
  120. $DSP->body .= $DSP->tr();
  121. $DSP->body .= $DSP->td('tableCellOne');
  122. // Whitelist
  123. $DSP->body .= $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist'.AMP.'P=view_whitelist', $LANG->line('ref_view_whitelist')));
  124. $DSP->body .= $DSP->td_c();
  125. $DSP->body .= $DSP->td('tableCellOne');
  126. if ($license = $PREFS->ini('license_number'))
  127. {
  128. $DSP->body .= $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist'.AMP.'P=pmachine_whitelist', $LANG->line('pmachine_whitelist'));
  129. }
  130. else
  131. {
  132. $DSP->body .= $DSP->qdiv('defaultBold', $LANG->line('pmachine_whitelist')).$DSP->qdiv('itemWrapper', $DSP->qdiv('highlight', $LANG->line('requires_license_number')));
  133. }
  134. $DSP->body .= $DSP->td_c();
  135. $DSP->body .= $DSP->tr_c();
  136. if ($SESS->userdata['group_id'] == '1')
  137. {
  138. $DSP->body .= $DSP->tr();
  139. $DSP->body .= $DSP->td('tableCellOne', '100%', '2');
  140. $htaccess_path = ( ! isset($_POST['htaccess_path']) OR $message == '') ? $PREFS->ini('htaccess_path') : $_POST['htaccess_path'];
  141. // .htaccess
  142. $DSP->body .= $DSP->form_open(array('action' => 'C=modules'.AMP.'M=blacklist'.AMP.'P=write_htaccess'));
  143. $DSP->body .= $DSP->qdiv('defaultBold', $LANG->line('write_htaccess_file'));
  144. $DSP->body .= $DSP->qdiv('itemWrapper', $LANG->line('htaccess_server_path', 'htaccess_path'));
  145. $DSP->body .= $DSP->qdiv('itemWrapper', $DSP->input_text('htaccess_path', $htaccess_path, '35', '100', 'input', '400px'));
  146. $DSP->body .= $DSP->qdiv('itemWrapper', $DSP->input_submit($LANG->line('submit')));
  147. $DSP->body .= $DSP->form_close();
  148. $DSP->body .= $DSP->td_c();
  149. $DSP->body .= $DSP->tr_c();
  150. }
  151. $DSP->body .= $DSP->table_c();
  152. }
  153. /* END */
  154. /** -------------------------
  155. /** Write .htaccess File
  156. /** -------------------------*/
  157. function write_htaccess($redirect=TRUE)
  158. {
  159. global $IN, $DB, $DSP, $LANG, $SESS, $PREFS, $EXT;
  160. if ($SESS->userdata['group_id'] != '1' OR $IN->GBL('htaccess_path') === FALSE)
  161. {
  162. if ($redirect === FALSE) return;
  163. return $this->blacklist_home();
  164. }
  165. if ( ! file_exists($IN->GBL('htaccess_path')) OR ! is_writeable($IN->GBL('htaccess_path')))
  166. {
  167. $DSP->body .= $DSP->error_message($LANG->line('invalid_htaccess_path'));
  168. return;
  169. }
  170. if ( ! class_exists('Admin'))
  171. {
  172. require PATH_CP.'cp.admin'.EXT;
  173. }
  174. if ($PREFS->ini('htaccess_path') !== FALSE)
  175. {
  176. Admin::update_config_file(array('htaccess_path' => $IN->GBL('htaccess_path')));
  177. }
  178. else
  179. {
  180. Admin::append_config_file(array('htaccess_path' => $IN->GBL('htaccess_path')));
  181. }
  182. if ( ! $fp = @fopen($IN->GBL('htaccess_path'), 'rb'))
  183. {
  184. $DSP->body .= $DSP->error_message($LANG->line('invalid_htaccess_path'));
  185. return;
  186. }
  187. flock($fp, LOCK_SH);
  188. $data = @fread($fp, filesize($IN->GBL('htaccess_path')));
  189. flock($fp, LOCK_UN);
  190. fclose($fp);
  191. if (preg_match("/##EE Spam Block(.*?)##End EE Spam Block/s", $data, $match))
  192. {
  193. $data = str_replace($match['0'], '', $data);
  194. }
  195. $data = trim($data);
  196. /** -----------------------------------------
  197. /** Current Blacklisted
  198. /** -----------------------------------------*/
  199. $query = $DB->query("SELECT * FROM exp_blacklisted");
  200. $old['url'] = array();
  201. $old['agent'] = array();
  202. $old['ip'] = array();
  203. if ($query->num_rows > 0)
  204. {
  205. foreach($query->result as $row)
  206. {
  207. $old_values = explode('|',trim($row['blacklisted_value']));
  208. for ($i=0, $s = sizeof($old_values); $i < $s; $i++)
  209. {
  210. if (trim($old_values[$i]) != '')
  211. {
  212. //$old[$row['blacklisted_type']][] = $old_values[$i];
  213. $old[$row['blacklisted_type']][] = preg_quote($old_values[$i]);
  214. }
  215. }
  216. }
  217. }
  218. /** --------------------------------------------------
  219. /** Right now we are only using URLs and IPs
  220. /** --------------------------------------------------*/
  221. $urls = '';
  222. while(sizeof($old['url']) > 0)
  223. {
  224. $urls .= 'SetEnvIfNoCase Referer ".*('.trim(implode('|', array_slice($old['url'], 0, 50))).').*" BadRef'.$this->LB;
  225. $old['url'] = array_slice($old['url'], 50);
  226. }
  227. $ips = '';
  228. while(sizeof($old['ip']) > 0)
  229. {
  230. $ips .= 'SetEnvIfNoCase REMOTE_ADDR "^('.trim(implode('|', array_slice($old['ip'], 0, 50))).').*" BadIP'.$this->LB;
  231. $old['ip'] = array_slice($old['ip'], 50);
  232. }
  233. $site = parse_url($PREFS->ini('site_url'));
  234. $domain = ( ! $PREFS->ini('cookie_domain')) ? '' : 'SetEnvIfNoCase Referer ".*('.preg_quote($PREFS->ini('cookie_domain')).').*" GoodHost'.$this->LB;
  235. $domain .= 'SetEnvIfNoCase Referer "^$" GoodHost'.$this->LB; // If no referrer, they be safe!
  236. $host = 'SetEnvIfNoCase Referer ".*('.preg_quote($site['host']).').*" GoodHost'.$this->LB;
  237. if ($urls != '' OR $ips != '')
  238. {
  239. $data .= $this->LB.$this->LB."##EE Spam Block".$this->LB
  240. . $urls
  241. . $ips
  242. . $domain
  243. . $host
  244. . "order deny,allow".$this->LB
  245. . "deny from env=BadRef".$this->LB
  246. . "deny from env=BadIP".$this->LB
  247. . "allow from env=GoodHost".$this->LB
  248. ."##End EE Spam Block".$this->LB.$this->LB;
  249. }
  250. // -------------------------------------------
  251. // 'blacklist_write_htaccess_data' hook.
  252. // - Modify what is written to the .htaccess file in Blacklist CP
  253. //
  254. if ($EXT->active_hook('blacklist_write_htaccess_data') === TRUE)
  255. {
  256. $data = $EXT->call_extension('blacklist_write_htaccess_data', $data, $old);
  257. if ($EXT->end_script === TRUE) return $edata;
  258. }
  259. //
  260. // -------------------------------------------
  261. if ( ! $fp = @fopen($IN->GBL('htaccess_path'), 'wb'))
  262. {
  263. $DSP->body .= $DSP->error_message($LANG->line('invalid_htaccess_path'));
  264. return;
  265. }
  266. flock($fp, LOCK_EX);
  267. fwrite($fp, $data);
  268. flock($fp, LOCK_UN);
  269. fclose($fp);
  270. if ($redirect === TRUE)
  271. {
  272. return $this->blacklist_home($LANG->line('htaccess_written_successfully'));
  273. }
  274. }
  275. /* END */
  276. /** -------------------------
  277. /** Update Blacklisted Items
  278. /** -------------------------*/
  279. function update_blacklist()
  280. {
  281. global $IN, $DB, $DSP, $LANG, $STAT, $EXT;
  282. if ( ! $DB->table_exists('exp_blacklisted'))
  283. {
  284. $DSP->body .= $DSP->error_message($LANG->line('ref_no_blacklist_table'));
  285. return;
  286. }
  287. // -------------------------------------------
  288. // 'blacklist_update_blacklist_start' hook.
  289. // - Rewrite what happens when the blacklist is updated
  290. //
  291. if ($EXT->active_hook('blacklist_update_blacklist_start') === TRUE)
  292. {
  293. $edata = $EXT->call_extension('blacklist_update_blacklist_start');
  294. if ($EXT->end_script === TRUE) return $edata;
  295. }
  296. //
  297. // -------------------------------------------
  298. /** -----------------------------------------
  299. /** Current Blacklisted
  300. /** -----------------------------------------*/
  301. $query = $DB->query("SELECT * FROM exp_blacklisted");
  302. $old['url'] = array();
  303. $old['agent'] = array();
  304. $old['ip'] = array();
  305. if ($query->num_rows > 0)
  306. {
  307. foreach($query->result as $row)
  308. {
  309. $old_values = explode('|',$row['blacklisted_value']);
  310. for ($i=0; $i < sizeof($old_values); $i++)
  311. {
  312. $old[$row['blacklisted_type']][] = $old_values[$i];
  313. }
  314. }
  315. }
  316. /** -----------------------------------------
  317. /** Current Whitelisted
  318. /** -----------------------------------------*/
  319. $query = $DB->query("SELECT * FROM exp_whitelisted");
  320. $white['url'] = array();
  321. $white['agent'] = array();
  322. $white['ip'] = array();
  323. if ($query->num_rows > 0)
  324. {
  325. foreach($query->result as $row)
  326. {
  327. $white_values = explode('|',$row['whitelisted_value']);
  328. for ($i=0; $i < sizeof($white_values); $i++)
  329. {
  330. if (trim($white_values[$i]) != '')
  331. {
  332. $white[$row['whitelisted_type']][] = $white_values[$i];
  333. }
  334. }
  335. }
  336. }
  337. /** ----------------------------------------------------------
  338. /** Update Blacklist with New Values sans Whitelist Matches
  339. /** ----------------------------------------------------------*/
  340. $default = array('ip', 'agent', 'url');
  341. $modified_weblogs = array();
  342. foreach ($default as $val)
  343. {
  344. if (isset($_POST[$val]))
  345. {
  346. $_POST[$val] = str_replace('[-]', '', $_POST[$val]);
  347. $_POST[$val] = str_replace('[+]', '', $_POST[$val]);
  348. $_POST[$val] = trim(stripslashes($_POST[$val]));
  349. $new_values = explode(NL,strip_tags($_POST[$val]));
  350. // Clean out user mistakes
  351. // and
  352. // Clean out Referrers/Trackbacks with new additions
  353. foreach ($new_values as $key => $this->value)
  354. {
  355. if (trim($this->value) == "" || trim($this->value) == NL)
  356. {
  357. unset($new_values[$key]);
  358. }
  359. elseif ( ! in_array($this->value,$old[$val]))
  360. {
  361. $name = ($val == 'url') ? 'from' : $val;
  362. $sql = "DELETE FROM exp_referrers WHERE ref_{$name} LIKE '%".$DB->escape_like_str($this->value)."%' ";
  363. if (sizeof($white[$val]) > 1)
  364. {
  365. $sql .= " AND ref_{$name} NOT LIKE '%".implode("%' AND ref_{$name} NOT LIKE '%", $DB->escape_like_str($white[$val]))."%'";
  366. }
  367. elseif (sizeof($white[$val]) > 0)
  368. {
  369. $sql .= "AND ref_{$name} NOT LIKE '%".$DB->escape_like_str($white[$val]['0'])."%'";
  370. }
  371. $DB->query($sql);
  372. if ($val == 'url' OR $val == 'ip')
  373. {
  374. $sql = " exp_trackbacks WHERE trackback_".$val." LIKE '%".$DB->escape_like_str($this->value)."%'";
  375. if (sizeof($white[$val]) > 1)
  376. {
  377. $sql .= " AND trackback_".$val." NOT LIKE '%".implode("%' AND trackback_".$val." NOT LIKE '%", $DB->escape_like_str($white[$val]))."%'";
  378. }
  379. elseif (sizeof($white[$val]) > 0)
  380. {
  381. $sql .= "AND trackback_".$val." NOT LIKE '%".$DB->escape_like_str($white[$val]['0'])."%'";
  382. }
  383. $query = $DB->query("SELECT entry_id, weblog_id FROM".$sql);
  384. if ($query->num_rows > 0)
  385. {
  386. $DB->query("DELETE FROM".$sql);
  387. foreach($query->result as $row)
  388. {
  389. $modified_weblogs[] = $row['weblog_id'];
  390. $results = $DB->query("SELECT COUNT(*) AS count from exp_trackbacks WHERE entry_id = '".$row['entry_id']."'");
  391. $results2 = $DB->query("SELECT MAX(trackback_date) AS max_date FROM exp_trackbacks
  392. WHERE entry_id = '".$row['entry_id']."'");
  393. $date = ($results2->num_rows == 0 OR ! is_numeric($results2->row['max_date'])) ? 0 : $results2->row['max_date'];
  394. $DB->query("UPDATE exp_weblog_titles
  395. SET trackback_total = '".$results->row['count']."',
  396. recent_trackback_date = '{$date}'
  397. WHERE entry_id = '".$row['entry_id']."'");
  398. }
  399. }
  400. }
  401. }
  402. }
  403. sort($new_values);
  404. $_POST[$val] = implode("|", array_unique($new_values));
  405. $DB->query("DELETE FROM exp_blacklisted WHERE blacklisted_type = '{$val}'");
  406. $data = array( 'blacklisted_type' => $val,
  407. 'blacklisted_value' => $_POST[$val]);
  408. $DB->query($DB->insert_string('exp_blacklisted', $data));
  409. }
  410. }
  411. // -------------------------------------------
  412. // 'blacklist_update_blacklist_end' hook.
  413. // - Add additional processing onto the end of the update blacklist routine
  414. //
  415. if ($EXT->active_hook('blacklist_update_blacklist_end') === TRUE)
  416. {
  417. $edata = $EXT->call_extension('blacklist_update_blacklist_end', $data);
  418. if ($EXT->end_script === TRUE) return $edata;
  419. }
  420. //
  421. // -------------------------------------------
  422. if (isset($modified_weblogs) && sizeof($modified_weblogs) > 0)
  423. {
  424. $modified_weblogs = array_unique($modified_weblogs);
  425. foreach($modified_weblogs as $weblog_id)
  426. {
  427. $STAT->update_trackback_stats($weblog_id);
  428. }
  429. }
  430. if ($IN->GBL('write_htaccess') !== FALSE)
  431. {
  432. $this->write_htaccess(FALSE);
  433. }
  434. return $this->view_blacklist($DSP->qdiv('success', $LANG->line('blacklist_updated')));
  435. }
  436. /* END */
  437. /** -------------------------
  438. /** Update Blacklist
  439. /** -------------------------*/
  440. function pmachine_blacklist()
  441. {
  442. global $DSP, $LANG, $PREFS, $DB, $STAT, $SESS;
  443. $DSP->title = $LANG->line('blacklist_module_name');
  444. $DSP->title = $LANG->line('blacklist_module_name');
  445. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist', $LANG->line('blacklist_module_name'));
  446. $DSP->crumb .= $DSP->crumb_item($LANG->line('pmachine_blacklist'));
  447. $r = '';
  448. if ( ! $DB->table_exists('exp_blacklisted'))
  449. {
  450. $r = $DSP->error_message($LANG->line('ref_no_blacklist_table'));
  451. $DSP->body .= $r;
  452. return;
  453. }
  454. if ( ! class_exists('XML_RPC'))
  455. {
  456. require PATH_CORE.'core.xmlrpc'.EXT;
  457. }
  458. /** -----------------------------------------
  459. /** Get Current Black List from pMachine.com
  460. /** -----------------------------------------*/
  461. if ( ! $license = $PREFS->ini('license_number'))
  462. {
  463. $r .= $DSP->error_message($LANG->line('ref_no_license'));
  464. $DSP->body .= $r;
  465. return;
  466. }
  467. $client = new XML_RPC_Client('/index.php','ping.expressionengine.com','80');
  468. $message = new XML_RPC_Message('ExpressionEngine.blacklist',array(new XML_RPC_Values($license)));
  469. if ( ! $result = $client->send($message))
  470. {
  471. $r .= $DSP->error_message($LANG->line('ref_blacklist_irretrievable'));
  472. $DSP->body .= $r;
  473. return;
  474. }
  475. if ( ! $result->value())
  476. {
  477. $r .= $DSP->error_message($LANG->line('ref_blacklist_irretrievable').BR.$result->errstr);
  478. $DSP->body .= $r;
  479. return;
  480. }
  481. elseif ( ! is_object($result->val))
  482. {
  483. $r .= $DSP->error_message($LANG->line('ref_blacklist_irretrievable'));
  484. $DSP->body .= $r;
  485. return;
  486. }
  487. // Array of our returned info
  488. $remote_info = $result->decode();
  489. if ($remote_info['flerror'] != 0)
  490. {
  491. $r .= $DSP->error_message($LANG->line('ref_blacklist_irretrievable').BR.$remote_info['message']);
  492. $DSP->body .= $r;
  493. return;
  494. }
  495. $new['url'] = ( ! isset($remote_info['urls']) || sizeof($remote_info['urls']) == 0) ? array() : explode('|',$remote_info['urls']);
  496. $new['agent'] = ( ! isset($remote_info['agents']) || sizeof($remote_info['agents']) == 0) ? array() : explode('|',$remote_info['agents']);
  497. $new['ip'] = ( ! isset($remote_info['ips']) || sizeof($remote_info['ips']) == 0) ? array() : explode('|',$remote_info['ips']);
  498. /** -----------------------------------------
  499. /** Add Current Blacklisted
  500. /** -----------------------------------------*/
  501. $query = $DB->query("SELECT * FROM exp_blacklisted");
  502. $old['url'] = array();
  503. $old['agent'] = array();
  504. $old['ip'] = array();
  505. if ($query->num_rows > 0)
  506. {
  507. foreach($query->result as $row)
  508. {
  509. $old_values = explode('|',$row['blacklisted_value']);
  510. for ($i=0; $i < sizeof($old_values); $i++)
  511. {
  512. $old[$row['blacklisted_type']][] = $old_values[$i];
  513. }
  514. }
  515. }
  516. /** -----------------------------------------
  517. /** Current Whitelisted
  518. /** -----------------------------------------*/
  519. $query = $DB->query("SELECT * FROM exp_whitelisted");
  520. $white['url'] = array();
  521. $white['agent'] = array();
  522. $white['ip'] = array();
  523. if ($query->num_rows > 0)
  524. {
  525. foreach($query->result as $row)
  526. {
  527. $white_values = explode('|',$row['whitelisted_value']);
  528. for ($i=0; $i < sizeof($white_values); $i++)
  529. {
  530. if (trim($white_values[$i]) != '')
  531. {
  532. $white[$row['whitelisted_type']][] = $white_values[$i];
  533. }
  534. }
  535. }
  536. }
  537. /** -----------------------------------------
  538. /** Check for uniqueness and sort
  539. /** -----------------------------------------*/
  540. $new['url'] = array_unique(array_merge($old['url'],$new['url']));
  541. $new['agent'] = array_unique(array_merge($old['agent'],$new['agent']));
  542. $new['ip'] = array_unique(array_merge($old['ip'],$new['ip']));
  543. sort($new['url']);
  544. sort($new['agent']);
  545. sort($new['ip']);
  546. /** -----------------------------------------
  547. /** Put blacklist info back into database
  548. /** -----------------------------------------*/
  549. $DB->query("DELETE FROM exp_blacklisted");
  550. foreach($new as $key => $value)
  551. {
  552. $blacklisted_value = implode('|',$value);
  553. $data = array( 'blacklisted_type' => $key,
  554. 'blacklisted_value' => $blacklisted_value);
  555. $DB->query($DB->insert_string('exp_blacklisted', $data));
  556. }
  557. /** ----------------------------------------------
  558. /** Using new blacklist members, clean out spam
  559. /** ----------------------------------------------*/
  560. $new['url'] = array_diff($new['url'], $old['url']);
  561. $new['agent'] = array_diff($new['agent'], $old['agent']);
  562. $new['ip'] = array_diff($new['ip'], $old['ip']);
  563. $modified_weblogs = array();
  564. foreach($new as $key => $value)
  565. {
  566. sort($value);
  567. $name = ($key == 'url') ? 'from' : $key;
  568. if (sizeof($value) > 0)
  569. {
  570. for($i=0; $i < sizeof($value); $i++)
  571. {
  572. if ($value[$i] != '')
  573. {
  574. $sql = "DELETE FROM exp_referrers WHERE ref_{$name} LIKE '%".$DB->escape_like_str($value[$i])."%' ";
  575. if (sizeof($white[$key]) > 1)
  576. {
  577. $sql .= " AND ref_{$name} NOT LIKE '%".implode("%' AND ref_{$name} NOT LIKE '%", $DB->escape_like_str($white[$key]))."%'";
  578. }
  579. elseif (sizeof($white[$key]) > 0)
  580. {
  581. $sql .= "AND ref_{$name} NOT LIKE '%".$DB->escape_like_str($white[$key]['0'])."%'";
  582. }
  583. $DB->query($sql);
  584. if ($key == 'url' OR $key == 'ip')
  585. {
  586. $sql = " exp_trackbacks WHERE trackback_".$key." LIKE '%".$DB->escape_like_str($value[$i])."%'";
  587. if (sizeof($white[$key]) > 1)
  588. {
  589. $sql .= " AND trackback_".$key." NOT LIKE '%".implode("%' AND trackback_".$key." NOT LIKE '%", $DB->escape_like_str($white[$key]))."%'";
  590. }
  591. elseif (sizeof($white[$key]) > 0)
  592. {
  593. $sql .= "AND trackback_".$key." NOT LIKE '%".$DB->escape_like_str($white[$key]['0'])."%'";
  594. }
  595. $query = $DB->query("SELECT entry_id, weblog_id FROM".$sql);
  596. if ($query->num_rows > 0)
  597. {
  598. $DB->query("DELETE FROM".$sql);
  599. foreach($query->result as $row)
  600. {
  601. $modified_weblogs[] = $row['weblog_id'];
  602. $results = $DB->query("SELECT COUNT(*) AS count from exp_trackbacks WHERE entry_id = '".$row['entry_id']."'");
  603. $results2 = $DB->query("SELECT MAX(trackback_date) AS max_date FROM exp_trackbacks
  604. WHERE entry_id = '".$row['entry_id']."'");
  605. $date = ($results2->num_rows == 0 OR !is_numeric($results2->row['max_date'])) ? 0 : $results2->row['max_date'];
  606. $DB->query("UPDATE exp_weblog_titles
  607. SET trackback_total = '".$results->row['count']."',
  608. recent_trackback_date = '{$date}'
  609. WHERE entry_id = '".$row['entry_id']."'");
  610. }
  611. }
  612. }
  613. }
  614. }
  615. }
  616. }
  617. if (isset($modified_weblogs) && sizeof($modified_weblogs) > 0)
  618. {
  619. $modified_weblogs = array_unique($modified_weblogs);
  620. foreach($modified_weblogs as $weblog_id)
  621. {
  622. $STAT->update_trackback_stats($weblog_id);
  623. }
  624. }
  625. /** -----------------------------------------
  626. /** Blacklist updated message
  627. /** -----------------------------------------*/
  628. $r .= $DSP->heading($LANG->line('pmachine_blacklist'));
  629. $r .= $DSP->qdiv('success', $LANG->line('blacklist_updated'));
  630. if ($SESS->userdata['group_id'] == '1' && $PREFS->ini('htaccess_path') != '')
  631. {
  632. // .htaccess
  633. $r .= BR.$DSP->form_open(array('action' => 'C=modules'.AMP.'M=blacklist'.AMP.'P=write_htaccess'));
  634. $r .= $DSP->input_hidden('htaccess_path', $PREFS->ini('htaccess_path'));
  635. $r .= $DSP->input_hidden('write_htaccess', 'y');
  636. $r .= $DSP->qdiv('box', $DSP->qdiv('defaultBold', $LANG->line('write_htaccess_file')).
  637. $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('update')))
  638. );
  639. }
  640. $DSP->body = $r;
  641. }
  642. /* END */
  643. /** -------------------------
  644. /** View Blacklisted
  645. /** -------------------------*/
  646. function view_blacklist($msg = '')
  647. {
  648. global $IN, $DSP, $LANG, $FNS, $DB, $PREFS, $SESS;
  649. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  650. $DSP->title = $LANG->line('blacklist_module_name');
  651. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist', $LANG->line('blacklist_module_name'));
  652. $DSP->crumb .= $DSP->crumb_item($LANG->line('ref_view_blacklist'));
  653. if ( ! $DB->table_exists('exp_blacklisted'))
  654. {
  655. $r = $DSP->error_message($LANG->line('ref_no_blacklist_table'));
  656. $DSP->body .= $r;
  657. return;
  658. }
  659. $r = $DSP->qdiv('tableHeading', $LANG->line('ref_view_blacklist'));
  660. if ($msg != '')
  661. $r .= $DSP->qdiv('successBox', $msg);
  662. $rows = array();
  663. $default = array('ip', 'url','agent');
  664. foreach ($default as $value)
  665. {
  666. $rows[$value] = '';
  667. }
  668. // Store by type with | between values
  669. $query = $DB->query("SELECT * FROM exp_blacklisted ORDER BY blacklisted_type asc");
  670. if ($query->num_rows != 0)
  671. {
  672. foreach($query->result as $row)
  673. {
  674. $rows[$row['blacklisted_type']] = $row['blacklisted_value'];
  675. }
  676. }
  677. $r .= $DSP->form_open(
  678. array(
  679. 'action' => 'C=modules'.AMP.'M=blacklist'.AMP.'P=update_blacklist',
  680. 'name' => 'target',
  681. 'id' => 'target'
  682. )
  683. );
  684. $r .= $DSP->table('tableBorder', '0', '', '100%').
  685. $DSP->tr().
  686. $DSP->table_qcell('tableHeadingAlt',
  687. array(
  688. $LANG->line('ref_type'),
  689. $LANG->line('ref_blacklisted')
  690. )
  691. ).
  692. $DSP->tr_c();
  693. $i = 0;
  694. //sort($rows);
  695. foreach($rows as $key => $value)
  696. {
  697. $style = ($i++ % 2) ? 'tableCellOneBold' : 'tableCellTwoBold';
  698. $r .= $DSP->tr();
  699. // Type
  700. switch($key)
  701. {
  702. case 'ip' :
  703. $name = $LANG->line('ref_ip');
  704. break;
  705. case 'agent' :
  706. $name = $LANG->line('ref_user_agent');
  707. break;
  708. default:
  709. $name = $LANG->line('ref_url');
  710. break;
  711. }
  712. $r .= $DSP->table_qcell($style, $name,'35%','top');
  713. // Value
  714. $value = str_replace('|',NL,$value);
  715. $r .= $DSP->table_qcell($style, $DSP->input_textarea($key, $value, 15, 'textarea', '100%'));
  716. $r .= $DSP->tr_c();
  717. }
  718. $r .= $DSP->table_c();
  719. if ($SESS->userdata['group_id'] == '1' && $PREFS->ini('htaccess_path') != '')
  720. {
  721. // .htaccess
  722. $r .= $DSP->qdiv('box', $DSP->input_checkbox('write_htaccess','y', 'y').' '.$LANG->line('write_htaccess_file'));
  723. $r .= $DSP->input_hidden('htaccess_path', $PREFS->ini('htaccess_path'));
  724. }
  725. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('update')));
  726. $r .= $DSP->form_close();
  727. $DSP->body .= $r;
  728. }
  729. /* END */
  730. // ===============================
  731. // WHITE LIST AREA
  732. // ===============================
  733. /** -------------------------
  734. /** Update Whitelisted Items
  735. /** -------------------------*/
  736. function update_whitelist()
  737. {
  738. global $IN, $DB, $DSP, $LANG, $EXT;
  739. if ( ! $DB->table_exists('exp_whitelisted'))
  740. {
  741. $DSP->body .= $DSP->error_message($LANG->line('ref_no_whitelist_table'));
  742. return;
  743. }
  744. // -------------------------------------------
  745. // 'blacklist_update_whitelist_start' hook.
  746. // - Rewrite what happens when the whitelist is updated
  747. //
  748. if ($EXT->active_hook('blacklist_update_whitelist_start') === TRUE)
  749. {
  750. $edata = $EXT->call_extension('blacklist_update_whitelist_start');
  751. if ($EXT->end_script === TRUE) return $edata;
  752. }
  753. //
  754. // -------------------------------------------
  755. /** -----------------------------------------
  756. /** Current Whitelisted
  757. /** -----------------------------------------*/
  758. $query = $DB->query("SELECT * FROM exp_whitelisted");
  759. $old['url'] = array();
  760. $old['agent'] = array();
  761. $old['ip'] = array();
  762. if ($query->num_rows > 0)
  763. {
  764. foreach($query->result as $row)
  765. {
  766. $old_values = explode('|',$row['whitelisted_value']);
  767. for ($i=0; $i < sizeof($old_values); $i++)
  768. {
  769. $old[$row['whitelisted_type']][] = $old_values[$i];
  770. }
  771. }
  772. }
  773. /** -----------------------------------------
  774. /** Update Whitelist with New Values
  775. /** -----------------------------------------*/
  776. $default = array('ip', 'agent', 'url');
  777. foreach ($default as $val)
  778. {
  779. if (isset($_POST[$val]))
  780. {
  781. $_POST[$val] = str_replace('[-]', '', $_POST[$val]);
  782. $_POST[$val] = str_replace('[+]', '', $_POST[$val]);
  783. $_POST[$val] = trim(stripslashes($_POST[$val]));
  784. $new_values = explode(NL,strip_tags($_POST[$val]));
  785. // Clean out user mistakes
  786. // and
  787. // Clean out Whitelists with new additions
  788. foreach ($new_values as $key => $value)
  789. {
  790. if (trim($value) == "" || trim($value) == NL)
  791. {
  792. unset($new_values[$key]);
  793. }
  794. }
  795. $_POST[$val] = implode("|",$new_values);
  796. $DB->query("DELETE FROM exp_whitelisted WHERE whitelisted_type = '{$val}'");
  797. $data = array( 'whitelisted_type' => $val,
  798. 'whitelisted_value' => $_POST[$val]);
  799. $DB->query($DB->insert_string('exp_whitelisted', $data));
  800. }
  801. }
  802. // -------------------------------------------
  803. // 'blacklist_update_whitelist_end' hook.
  804. // - Add processing for when the whitelist is updated
  805. //
  806. if ($EXT->active_hook('blacklist_update_whitelist_end') === TRUE)
  807. {
  808. $edata = $EXT->call_extension('blacklist_update_whitelist_end', $data);
  809. if ($EXT->end_script === TRUE) return $edata;
  810. }
  811. //
  812. // -------------------------------------------
  813. return $this->view_whitelist($DSP->qdiv('success', $LANG->line('whitelist_updated')));
  814. }
  815. /* END */
  816. /** -------------------------
  817. /** Update Whitelist
  818. /** -------------------------*/
  819. function pmachine_whitelist()
  820. {
  821. global $DSP, $LANG, $PREFS, $DB;
  822. $DSP->title = $LANG->line('blacklist_module_name');
  823. $DSP->title = $LANG->line('blacklist_module_name');
  824. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist', $LANG->line('blacklist_module_name'));
  825. $DSP->crumb .= $DSP->crumb_item($LANG->line('pmachine_whitelist'));
  826. $r = '';
  827. if ( ! $DB->table_exists('exp_whitelisted'))
  828. {
  829. $r = $DSP->error_message($LANG->line('ref_no_whitelist_table'));
  830. $DSP->body .= $r;
  831. return;
  832. }
  833. if ( ! class_exists('XML_RPC'))
  834. {
  835. require PATH_CORE.'core.xmlrpc'.EXT;
  836. }
  837. /** -----------------------------------------
  838. /** Get Current Black List from pMachine.com
  839. /** -----------------------------------------*/
  840. if ( ! $license = $PREFS->ini('license_number'))
  841. {
  842. $r .= $DSP->error_message($LANG->line('ref_no_license'));
  843. $DSP->body .= $r;
  844. return;
  845. }
  846. $client = new XML_RPC_Client('/index.php','ping.expressionengine.com','80');
  847. $message = new XML_RPC_Message('ExpressionEngine.whitelist',array(new XML_RPC_Values($license)));
  848. if ( ! $result = $client->send($message))
  849. {
  850. $r .= $DSP->error_message($LANG->line('ref_whitelist_irretrievable'));
  851. $DSP->body .= $r;
  852. return;
  853. }
  854. if ( ! $result->value())
  855. {
  856. $r .= $DSP->error_message($LANG->line('ref_whitelist_irretrievable').BR.$result->errstr);
  857. $DSP->body .= $r;
  858. return;
  859. }
  860. elseif ( ! is_object($result->val))
  861. {
  862. $r .= $DSP->error_message($LANG->line('ref_whitelist_irretrievable'));
  863. $DSP->body .= $r;
  864. return;
  865. }
  866. // Array of our returned info
  867. $remote_info = $result->decode();
  868. if ($remote_info['flerror'] != 0)
  869. {
  870. $r .= $DSP->error_message($LANG->line('ref_whitelist_irretrievable').BR.$remote_info['message']);
  871. $DSP->body .= $r;
  872. return;
  873. }
  874. $new['url'] = ( ! isset($remote_info['urls']) || sizeof($remote_info['urls']) == 0) ? array() : explode('|',$remote_info['urls']);
  875. $new['agent'] = ( ! isset($remote_info['agents']) || sizeof($remote_info['agents']) == 0) ? array() : explode('|',$remote_info['agents']);
  876. $new['ip'] = ( ! isset($remote_info['ips']) || sizeof($remote_info['ips']) == 0) ? array() : explode('|',$remote_info['ips']);
  877. /** -----------------------------------------
  878. /** Add Current Whitelisted
  879. /** -----------------------------------------*/
  880. $query = $DB->query("SELECT * FROM exp_whitelisted");
  881. $old['url'] = array();
  882. $old['agent'] = array();
  883. $old['ip'] = array();
  884. if ($query->num_rows > 0)
  885. {
  886. foreach($query->result as $row)
  887. {
  888. $old_values = explode('|',$row['whitelisted_value']);
  889. for ($i=0; $i < sizeof($old_values); $i++)
  890. {
  891. $old[$row['whitelisted_type']][] = $old_values[$i];
  892. }
  893. }
  894. }
  895. /** -----------------------------------------
  896. /** Check for uniqueness and sort
  897. /** -----------------------------------------*/
  898. $new['url'] = array_unique(array_merge($old['url'],$new['url']));
  899. $new['agent'] = array_unique(array_merge($old['agent'],$new['agent']));
  900. $new['ip'] = array_unique(array_merge($old['ip'],$new['ip']));
  901. sort($new['url']);
  902. sort($new['agent']);
  903. sort($new['ip']);
  904. /** -----------------------------------------
  905. /** Put whitelist info back into database
  906. /** -----------------------------------------*/
  907. $DB->query("DELETE FROM exp_whitelisted");
  908. foreach($new as $key => $value)
  909. {
  910. $whitelisted_value = implode('|',$value);
  911. $data = array( 'whitelisted_type' => $key,
  912. 'whitelisted_value' => $whitelisted_value);
  913. $DB->query($DB->insert_string('exp_whitelisted', $data));
  914. }
  915. /** -----------------------------------------
  916. /** Whitelist updated message
  917. /** -----------------------------------------*/
  918. $r .= $DSP->heading($LANG->line('pmachine_whitelist'));
  919. $r .= $DSP->qdiv('success', $LANG->line('whitelist_updated'));
  920. $DSP->body = $r;
  921. }
  922. /* END */
  923. /** -------------------------
  924. /** View Whitelisted
  925. /** -------------------------*/
  926. function view_whitelist($msg = '')
  927. {
  928. global $IN, $DSP, $LANG, $FNS, $DB, $PREFS;
  929. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  930. $DSP->title = $LANG->line('blacklist_module_name');
  931. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=modules'.AMP.'M=blacklist', $LANG->line('blacklist_module_name'));
  932. $DSP->crumb .= $DSP->crumb_item($LANG->line('ref_view_whitelist'));
  933. if ( ! $DB->table_exists('exp_whitelisted'))
  934. {
  935. $r = $DSP->error_message($LANG->line('ref_no_whitelist_table'));
  936. $DSP->body .= $r;
  937. return;
  938. }
  939. $r = $DSP->heading($LANG->line('ref_view_whitelist'));
  940. $r .= $msg;
  941. $rows = array();
  942. $default = array('ip', 'url','agent');
  943. foreach ($default as $value)
  944. {
  945. $rows[$value] = '';
  946. }
  947. // Store by type with | between values
  948. $query = $DB->query("SELECT * FROM exp_whitelisted ORDER BY whitelisted_type asc");
  949. if ($query->num_rows != 0)
  950. {
  951. foreach($query->result as $row)
  952. {
  953. $rows[$row['whitelisted_type']] = $row['whitelisted_value'];
  954. }
  955. }
  956. $r .= $DSP->form_open(
  957. array(
  958. 'action' => 'C=modules'.AMP.'M=blacklist'.AMP.'P=update_whitelist',
  959. 'name' => 'target',
  960. 'id' => 'target'
  961. )
  962. );
  963. $r .= $DSP->table('tableBorder', '0', '', '100%').
  964. $DSP->tr().
  965. $DSP->table_qcell('tableHeading',
  966. array(
  967. $LANG->line('ref_type'),
  968. $LANG->line('ref_whitelisted')
  969. )
  970. ).
  971. $DSP->tr_c();
  972. $i = 0;
  973. //sort($rows);
  974. foreach($rows as $key => $value)
  975. {
  976. $style = ($i++ % 2) ? 'tableCellOneBold' : 'tableCellTwoBold';
  977. $r .= $DSP->tr();
  978. // Type
  979. switch($key)
  980. {
  981. case 'ip' :
  982. $name = $LANG->line('ref_ip');
  983. break;
  984. case 'agent' :
  985. $name = $LANG->line('ref_user_agent');
  986. break;
  987. default:
  988. $name = $LANG->line('ref_url');
  989. break;
  990. }
  991. $r .= $DSP->table_qcell($style, $name,'35%','top');
  992. // Value
  993. $value = str_replace('|',NL,$value);
  994. $r .= $DSP->table_qcell($style, $DSP->input_textarea($key, $value, 15, 'textarea', '100%'));
  995. }
  996. $r .= $DSP->table_c();
  997. $r .= $DSP->qdiv('itemWrapper', BR.$DSP->input_submit($LANG->line('update')));
  998. $r .= $DSP->form_close();
  999. $DSP->body .= $r;
  1000. }
  1001. /* END */
  1002. /** -------------------------
  1003. /** Module installer
  1004. /** -------------------------*/
  1005. function blacklist_module_install()
  1006. {
  1007. global $DB;
  1008. $sql[] = "INSERT INTO exp_modules (module_id, module_name, module_version, has_cp_backend) VALUES ('', 'Blacklist', '$this->version', 'y')";
  1009. $sql[] = "CREATE TABLE IF NOT EXISTS `exp_blacklisted` (
  1010. `blacklisted_type` VARCHAR( 20 ) NOT NULL ,
  1011. `blacklisted_value` TEXT NOT NULL);";
  1012. $sql[] = "CREATE TABLE IF NOT EXISTS `exp_whitelisted` (
  1013. `whitelisted_type` VARCHAR( 20 ) NOT NULL ,
  1014. `whitelisted_value` TEXT NOT NULL);";
  1015. foreach ($sql as $query)
  1016. {
  1017. $DB->query($query);
  1018. }
  1019. return true;
  1020. }
  1021. /* END */
  1022. /** -------------------------
  1023. /** Module de-installer
  1024. /** -------------------------*/
  1025. function blacklist_module_deinstall()
  1026. {
  1027. global $DB;
  1028. $query = $DB->query("SELECT module_id FROM exp_modules WHERE module_name = 'Blacklist'");
  1029. $sql[] = "DELETE FROM exp_module_member_groups WHERE module_id = '".$query->row['module_id']."'";
  1030. $sql[] = "DELETE FROM exp_modules WHERE module_name = 'Blacklist'";
  1031. $sql[] = "DELETE FROM exp_actions WHERE class = 'Blacklist'";
  1032. $sql[] = "DELETE FROM exp_actions WHERE class = 'Blacklist_CP'";
  1033. $sql[] = "DROP TABLE IF EXISTS exp_blacklisted";
  1034. $sql[] = "DROP TABLE IF EXISTS exp_whitelisted";
  1035. foreach ($sql as $query)
  1036. {
  1037. $DB->query($query);
  1038. }
  1039. return true;
  1040. }
  1041. /* END */
  1042. /** -------------------------
  1043. /** Whitelist cleaning for new Blacklist items
  1044. /** -------------------------*/
  1045. function whitelist_clean($var)
  1046. {
  1047. return stristr($var, $this->value);
  1048. }
  1049. /* END */
  1050. }
  1051. // END CLASS
  1052. ?>