BxAntispamModule.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 DolphinModules
  8. *
  9. * @{
  10. */
  11. // TODO: add checking on join form
  12. bx_import('BxDolModule');
  13. class BxAntispamModule extends BxDolModule
  14. {
  15. function __construct(&$aModule)
  16. {
  17. parent::__construct($aModule);
  18. }
  19. function serviceIpTable ()
  20. {
  21. return $this->_grid('bx_antispam_grid_ip_table');
  22. }
  23. function serviceDnsblList ()
  24. {
  25. return $this->_grid('bx_antispam_grid_dnsbl');
  26. }
  27. function serviceBlockLog ()
  28. {
  29. return $this->_grid('bx_antispam_grid_block_log');
  30. }
  31. /**
  32. * Check text for spam.
  33. * First it check if IP is whitelisted(or under cron execution or user is admin) - for whitelisted IPs check for spam isn't performed,
  34. * then it checks URLs found in text for DNSURI black lists (@see BxAntispamDNSURIBlacklists),
  35. * then it checks text in Akismet service (@see BxAntispamAkismet).
  36. * It can send report if spam is found or tries to inform caller to block the content (depending on configuration).
  37. *
  38. * @param $sContent content to check for spam
  39. * @param $sIp IP address of content poster
  40. * @param $isStripSlashes slashes parameter:
  41. * BX_SLASHES_AUTO - automatically detect magic_quotes_gpc setting
  42. * BX_SLASHES_NO_ACTION - do not perform any action with slashes
  43. * @return true if spam detected and content shouln't be recorded, false if content should be processed as usual.
  44. */
  45. function serviceIsSpam ($sContent, $sIp = '', $isStripSlashes = BX_SLASHES_AUTO)
  46. {
  47. if (defined('BX_DOL_CRON_EXECUTE') || isAdmin())
  48. return false;
  49. if ($this->serviceIsIpWhitelisted($sIp))
  50. return false;
  51. if (get_magic_quotes_gpc() && $isStripSlashes == BX_SLASHES_AUTO)
  52. $sContent = stripslashes($sContent);
  53. $bRet = false;
  54. if ('on' == $this->_oConfig->getAntispamOption('uridnsbl_enable')) {
  55. $oDNSURIBlacklists = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
  56. if ($oDNSURIBlacklists->isSpam($sContent)) {
  57. $oDNSURIBlacklists->onPositiveDetection($sContent);
  58. $bRet = true;
  59. }
  60. }
  61. if (!$bRet && 'on' == $this->_oConfig->getAntispamOption('akismet_enable')) {
  62. $oAkismet = bx_instance('BxAntispamAkismet', array(), $this->_aModule);
  63. if ($oAkismet->isSpam($sContent)) {
  64. $oAkismet->onPositiveDetection($sContent);
  65. $bRet = true;
  66. }
  67. }
  68. bx_alert('bx_antispam', 'is_spam', bx_get_logged_profile_id(), 0, array('content' => $sContent, 'ip' => $sIp, 'result' => &$ret));
  69. if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_report')) {
  70. $iProfileId = getLoggedId();
  71. $aPlus = array(
  72. 'SpammerUrl' => getProfileLink($iProfileId),
  73. 'SpammerNickName' => getNickName($iProfileId),
  74. 'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
  75. 'Get' => print_r($_GET, true),
  76. 'SpamContent' => htmlspecialchars_adv($sContent),
  77. );
  78. bx_import('BxDolEmailTemplates');
  79. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_SpamReportAuto', $aPlus);
  80. if (!$aTemplate)
  81. trigger_error('Email template or translation missing: t_SpamReportAuto', E_USER_ERROR);
  82. sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
  83. }
  84. if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_block'))
  85. return true;
  86. return false;
  87. }
  88. /**
  89. * Perform complex check if user is allowed to login.
  90. * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
  91. * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted).
  92. *
  93. * @param $sIp IP to check, or empty for current IP
  94. * @return empty string - if join should be allowed, error message - if join should be blocked
  95. */
  96. function serviceCheckLogin ($sIp = '')
  97. {
  98. $bLoginBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'));
  99. $sErrorMsg = '';
  100. $sNote = $bLoginBlock ? 'login block' : 'login log';
  101. if (!$sIp)
  102. $sIp = getVisitorIP();
  103. if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
  104. $sErrorMsg = $this->getErrorMessageIpBlocked();
  105. if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote) && $bLoginBlock)
  106. $sErrorMsg = $this->getErrorMessageSpam();
  107. return $sErrorMsg;
  108. }
  109. /**
  110. * Perform complex check if user is allowed to join.
  111. * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
  112. * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted),
  113. * then it checks in StopForumSpam service (@see BxAntispamStopForumSpam).
  114. *
  115. * TODO: if dnsbl_behaviour == approval, inform caller to set account to approval status on positive detection
  116. *
  117. * @param $sCurIP IP to check, or empty for current IP
  118. * @return empty string - if join should be allowed, error message - if join should be blocked
  119. */
  120. function serviceCheckJoin ($sEmail, $sIp = '')
  121. {
  122. $bJoinBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'));
  123. $bApproval = false;
  124. $sErrorMsg = '';
  125. $sNote = $bJoinBlock ? 'join block' : 'join approval';
  126. if (!$sIp)
  127. $sIp = getVisitorIP();
  128. if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
  129. $sErrorMsg = $this->getErrorMessageIpBlocked();
  130. if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote)) {
  131. if ('approval' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'))
  132. $bApproval = true;
  133. else
  134. $sErrorMsg = $this->getErrorMessageSpam();
  135. }
  136. if (!$sErrorMsg) {
  137. $oStopForumSpam = bx_instance('BxAntispamStopForumSpam', array(), $this->_aModule);
  138. if ($oStopForumSpam->isSpammer(array('email' => $sEmail, 'ip' => $sIp), $sNote))
  139. $sErrorMsg = $this->getErrorMessageSpam();
  140. }
  141. bx_alert('bx_antispam', 'check_join', bx_get_logged_profile_id(), 0, array('email' => $sEmail, 'ip' => $sIp, 'error_msg' => &$sErrorMsg));
  142. return $sErrorMsg;
  143. }
  144. /**
  145. * Check if IP is blacklisted in some DNS chain (@see BxAntispamDNSBlacklists).
  146. *
  147. * @param $sCurIP IP to check, or empty for current IP
  148. * @param $sNote [optional] place where checking is performed, for example 'join', 'login'
  149. * @return true if IP blacklisted and not whiteloisted, or false if under cron execution or if IP isn't blacklisted
  150. */
  151. function serviceIsIpDnsBlacklisted($sCurIP = '', $sNote = '')
  152. {
  153. if (defined('BX_DOL_CRON_EXECUTE'))
  154. return false;
  155. if (!$sCurIP)
  156. $sCurIP = getVisitorIP();
  157. if ($this->serviceIsIpWhitelisted($sCurIP))
  158. return false;
  159. $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
  160. 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)) {
  161. $o->onPositiveDetection ($sCurIP, $sNote);
  162. return true;
  163. }
  164. return false;
  165. }
  166. /**
  167. * @see BxAntispamIP::isIpWhitelisted
  168. */
  169. function serviceIsIpWhitelisted($sIp = '')
  170. {
  171. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  172. return $o->isIpWhitelisted($sIp);
  173. }
  174. /**
  175. * @see BxAntispamIP::isIpBlocked
  176. */
  177. function serviceIsIpBlocked($sIp = '')
  178. {
  179. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  180. return $o->isIpBlocked($sIp);
  181. }
  182. /**
  183. * @see BxAntispamIP::blockIp
  184. */
  185. function serviceBlockIp($mixedIP, $iExpirationInSec = 86400, $sComment = '')
  186. {
  187. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  188. return $o->blockIp($mixedIP, $iExpirationInSec, $sComment);
  189. }
  190. protected function getErrorMessageIpBlocked ()
  191. {
  192. bx_import('BxDolLanguages');
  193. return _t('_bx_antispam_ip_blocked', $this->getErrorMessageSubmitFalsePositiveReport());
  194. }
  195. protected function getErrorMessageSpam ()
  196. {
  197. bx_import('BxDolLanguages');
  198. return _t('_bx_antispam_spam_detected', $this->getErrorMessageSubmitFalsePositiveReport());
  199. }
  200. protected function getErrorMessageSubmitFalsePositiveReport ()
  201. {
  202. if (BxDolRequest::serviceExists('bx_contact', 'get_contact_page_url') && ($sUrl = BxDolService::call('bx_contact', 'get_contact_page_url')))
  203. return _t('_bx_antispam_submit_false_positive_report', $sUrl);
  204. return '';
  205. }
  206. protected function _grid ($sObjectGrid)
  207. {
  208. bx_import('BxDolGrid');
  209. $oGrid = BxDolGrid::getObjectInstance($sObjectGrid);
  210. return $oGrid ? $oGrid->getCode() : '';
  211. }
  212. }
  213. /** @} */