BxAntispamModule.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup Antispam Antispam
  7. * @ingroup TridentModules
  8. *
  9. * @{
  10. */
  11. bx_import('BxDolModule');
  12. class BxAntispamModule extends BxDolModule
  13. {
  14. public function __construct(&$aModule)
  15. {
  16. parent::__construct($aModule);
  17. }
  18. public function serviceIpTable ()
  19. {
  20. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  21. $s = _t('_bx_antispam_ip_table_status', mb_strtolower($o->getIpTableConfigTitle((int)getParam('bx_antispam_ip_list_type'))));
  22. $s .= $this->_grid('bx_antispam_grid_ip_table');
  23. return $s;
  24. }
  25. public function serviceDnsblList ()
  26. {
  27. bx_import('BxTemplFunctions');
  28. $s = _t('_bx_antispam_dnsbl_status',
  29. BxTemplFunctions::getInstance()->statusOnOff((bool)$this->_oConfig->getAntispamOption('dnsbl_enable'), true),
  30. BxTemplFunctions::getInstance()->statusOnOff((bool)$this->_oConfig->getAntispamOption('uridnsbl_enable'), true),
  31. mb_strtolower(_t('_bx_antispam_dnsbl_behaviour_login_' . $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'))),
  32. mb_strtolower(_t('_bx_antispam_dnsbl_behaviour_join_' . $this->_oConfig->getAntispamOption('dnsbl_behaviour_join')))
  33. );
  34. $s .= $this->_grid('bx_antispam_grid_dnsbl');
  35. return $s;
  36. }
  37. public function serviceBlockLog ()
  38. {
  39. return $this->_grid('bx_antispam_grid_block_log');
  40. }
  41. /**
  42. * Check text for spam.
  43. * First it check if IP is whitelisted(or under cron execution or user is admin) - for whitelisted IPs check for spam isn't performed,
  44. * then it checks URLs found in text for DNSURI black lists (@see BxAntispamDNSURIBlacklists),
  45. * then it checks text in Akismet service (@see BxAntispamAkismet).
  46. * It can send report if spam is found or tries to inform caller to block the content (depending on configuration).
  47. *
  48. * @param $sContent content to check for spam
  49. * @param $sIp IP address of content poster
  50. * @param $isStripSlashes slashes parameter:
  51. * BX_SLASHES_AUTO - automatically detect magic_quotes_gpc setting
  52. * BX_SLASHES_NO_ACTION - do not perform any action with slashes
  53. * @return true if spam detected and content shouln't be recorded, false if content should be processed as usual.
  54. */
  55. public function serviceIsSpam ($sContent, $sIp = '', $isStripSlashes = BX_SLASHES_AUTO)
  56. {
  57. if (defined('BX_DOL_CRON_EXECUTE') || isAdmin())
  58. return false;
  59. if ($this->serviceIsIpWhitelisted($sIp))
  60. return false;
  61. if (get_magic_quotes_gpc() && $isStripSlashes == BX_SLASHES_AUTO)
  62. $sContent = stripslashes($sContent);
  63. $bRet = false;
  64. if ('on' == $this->_oConfig->getAntispamOption('uridnsbl_enable')) {
  65. $oDNSURIBlacklists = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
  66. if ($oDNSURIBlacklists->isSpam($sContent)) {
  67. $oDNSURIBlacklists->onPositiveDetection($sContent);
  68. $bRet = true;
  69. }
  70. }
  71. if (!$bRet && 'on' == $this->_oConfig->getAntispamOption('akismet_enable')) {
  72. $oAkismet = bx_instance('BxAntispamAkismet', array(), $this->_aModule);
  73. if ($oAkismet->isSpam($sContent)) {
  74. $oAkismet->onPositiveDetection($sContent);
  75. $bRet = true;
  76. }
  77. }
  78. if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_report')) {
  79. $oProfile = BxDolProfile::getInstance();
  80. $aPlus = array(
  81. 'SpammerUrl' => $oProfile->getUrl(),
  82. 'SpammerNickName' => $oProfile->getDisplayName(),
  83. 'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
  84. 'Get' => print_r($_GET, true),
  85. 'Post' => print_r($_POST, true),
  86. 'SpamContent' => htmlspecialchars_adv($sContent),
  87. );
  88. bx_import('BxDolEmailTemplates');
  89. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('bx_antispam_spam_report', $aPlus);
  90. if (!$aTemplate)
  91. trigger_error('Email template or translation missing: bx_antispam_spam_report', E_USER_ERROR);
  92. sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
  93. }
  94. if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_block'))
  95. return true;
  96. return false;
  97. }
  98. /**
  99. * Perform complex check if user is allowed to login.
  100. * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
  101. * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted).
  102. *
  103. * @param $sIp IP to check, or empty for current IP
  104. * @return empty string - if join should be allowed, error message - if join should be blocked
  105. */
  106. public function serviceCheckLogin ($sIp = '')
  107. {
  108. $bLoginBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'));
  109. $sErrorMsg = '';
  110. $sNote = $bLoginBlock ? 'login block' : 'login log';
  111. if (!$sIp)
  112. $sIp = getVisitorIP();
  113. if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
  114. $sErrorMsg = $this->getErrorMessageIpBlocked();
  115. if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote) && $bLoginBlock)
  116. $sErrorMsg = $this->getErrorMessageSpam();
  117. return $sErrorMsg;
  118. }
  119. /**
  120. * Perform complex check if user is allowed to join.
  121. * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
  122. * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted),
  123. * then it checks in StopForumSpam service (@see BxAntispamStopForumSpam).
  124. *
  125. * @param $sCurIP IP to check, or empty for current IP
  126. * @return empty string - if join should be allowed, error message - if join should be blocked
  127. */
  128. public function serviceCheckJoin ($sEmail, &$bApproval, $sIp = '')
  129. {
  130. $bJoinBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'));
  131. $bApproval = false;
  132. $sErrorMsg = '';
  133. $sNote = $bJoinBlock ? 'join block' : 'join approval';
  134. if (!$sIp)
  135. $sIp = getVisitorIP();
  136. if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
  137. $sErrorMsg = $this->getErrorMessageIpBlocked();
  138. if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote)) {
  139. if ('approval' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'))
  140. $bApproval = true;
  141. else
  142. $sErrorMsg = $this->getErrorMessageSpam();
  143. }
  144. if (!$sErrorMsg) {
  145. $oStopForumSpam = bx_instance('BxAntispamStopForumSpam', array(), $this->_aModule);
  146. if ($oStopForumSpam->isSpammer(array('email' => $sEmail, 'ip' => $sIp), $sNote))
  147. $sErrorMsg = $this->getErrorMessageSpam();
  148. }
  149. return $sErrorMsg;
  150. }
  151. /**
  152. * Check if IP is blacklisted in some DNS chain (@see BxAntispamDNSBlacklists).
  153. *
  154. * @param $sCurIP IP to check, or empty for current IP
  155. * @param $sNote [optional] place where checking is performed, for example 'join', 'login'
  156. * @return true if IP blacklisted and not whiteloisted, or false if under cron execution or if IP isn't blacklisted
  157. */
  158. public function serviceIsIpDnsBlacklisted($sCurIP = '', $sNote = '')
  159. {
  160. if (defined('BX_DOL_CRON_EXECUTE'))
  161. return false;
  162. if (!$sCurIP)
  163. $sCurIP = getVisitorIP();
  164. if ($this->serviceIsIpWhitelisted($sCurIP))
  165. return false;
  166. $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
  167. if (BX_DOL_DNSBL_POSITIVE == $o->dnsbl_lookup_ip(BX_DOL_DNSBL_CHAIN_SPAMMERS, $sCurIP) && BX_DOL_DNSBL_POSITIVE != $o->dnsbl_lookup_ip(BX_DOL_DNSBL_CHAIN_WHITELIST, $sCurIP)) {
  168. $o->onPositiveDetection ($sCurIP, $sNote);
  169. return true;
  170. }
  171. return false;
  172. }
  173. /**
  174. * @see BxAntispamIP::isIpWhitelisted
  175. */
  176. public function serviceIsIpWhitelisted($sIp = '')
  177. {
  178. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  179. return $o->isIpWhitelisted($sIp);
  180. }
  181. /**
  182. * @see BxAntispamIP::isIpBlocked
  183. */
  184. public function serviceIsIpBlocked($sIp = '')
  185. {
  186. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  187. return $o->isIpBlocked($sIp);
  188. }
  189. /**
  190. * @see BxAntispamIP::blockIp
  191. */
  192. public function serviceBlockIp($mixedIP, $iExpirationInSec = 86400, $sComment = '')
  193. {
  194. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  195. return $o->blockIp($mixedIP, $iExpirationInSec, $sComment);
  196. }
  197. /**
  198. * @see BxAntispamIP::pruning
  199. */
  200. public function servicePruning()
  201. {
  202. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  203. return $o->pruning();
  204. }
  205. /**
  206. * @see BxAntispamIP::pruning
  207. */
  208. public function serviceConfigValues($s)
  209. {
  210. switch ($s) {
  211. case 'ip_table':
  212. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  213. return $o->getIpTableConfigValues();
  214. case 'dnsbl_login':
  215. $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
  216. return $o->getDNSBLConfigValues();
  217. case 'dnsbl_join';
  218. $o = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
  219. return $o->getURIDNSBLConfigValues();
  220. }
  221. }
  222. protected function getErrorMessageIpBlocked ()
  223. {
  224. bx_import('BxDolLanguages');
  225. return _t('_bx_antispam_ip_blocked', $this->getErrorMessageSubmitFalsePositiveReport());
  226. }
  227. protected function getErrorMessageSpam ()
  228. {
  229. bx_import('BxDolLanguages');
  230. return _t('_bx_antispam_spam_detected', $this->getErrorMessageSubmitFalsePositiveReport());
  231. }
  232. protected function getErrorMessageSubmitFalsePositiveReport ()
  233. {
  234. if (BxDolRequest::serviceExists('bx_contact', 'get_contact_page_url') && ($sUrl = BxDolService::call('bx_contact', 'get_contact_page_url')))
  235. return _t('_bx_antispam_submit_false_positive_report', $sUrl);
  236. return '';
  237. }
  238. protected function _grid ($sObjectGrid)
  239. {
  240. bx_import('BxDolGrid');
  241. $oGrid = BxDolGrid::getObjectInstance($sObjectGrid);
  242. return $oGrid ? $oGrid->getCode() : '';
  243. }
  244. }
  245. /** @} */