Skip to content

Commit

Permalink
Merge pull request #6 from matdave/main
Browse files Browse the repository at this point in the history
Fixes after testing on 3.x
  • Loading branch information
matdave authored Feb 14, 2024
2 parents 6d3604f + bf6f09c commit bf50d0a
Show file tree
Hide file tree
Showing 9 changed files with 407 additions and 90 deletions.
2 changes: 1 addition & 1 deletion _build/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Rampart",
"lowCaseName": "rampart",
"description": "Rampart is a robust anti-spam tool for MODX Revolution.",
"version": "2.0.0",
"version": "2.0.1-pl",
"author": "splittingred",
"package": {
"menus": [
Expand Down
2 changes: 1 addition & 1 deletion _build/gpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Rampart
namespace: Rampart
lowCaseName: rampart
description: Rampart is a robust anti-spam tool for MODX Revolution.
version: 2.0.0
version: 2.0.1
author: splittingred
menus:
- text: rampart
Expand Down
4 changes: 4 additions & 0 deletions core/components/rampart/docs/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Changelog for Rampart.

Rampart 2.0.1
==============
- Fixing issues with MODX 3 support

Rampart 2.0.0
==============
- Rebuild Rampart for MODX 3 Support
Expand Down
212 changes: 212 additions & 0 deletions core/components/rampart/model/rampart/rampart.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,216 @@ public function checkBanList($result)
}
return $result;
}


public function runStopForumSpamChecks(array $result)
{
/* Run StopForumSpam checks */
$sfspam = new \Rampart\v2\StopForumSpam($this->modx);
$spamResult = $sfspam->check(
$result[RampartBase::IP],
$result[RampartBase::EMAIL],
$result[RampartBase::USERNAME]
);
if (!empty($spamResult)) {
if (in_array('Ip', $spamResult) && in_array('Username', $spamResult)) {
/**
* If ip AND username match, moderate user
*/
$result[RampartBase::STATUS] = RampartBase::STATUS_MODERATED;
$result[RampartBase::REASON] = 'ipusername';
} elseif (in_array('Email', $spamResult)) {
/**
* Moderate users who match the email
*/
$result[RampartBase::STATUS] = RampartBase::STATUS_MODERATED;
$result[RampartBase::REASON] = 'email';
} elseif (in_array('Ip', $spamResult)) {
$threshold = $this->modx->getOption(
'rampart.sfs_ipban_threshold',
null,
25
); /* threshold of reported times by SFS */
$expiration = $this->modx->getOption(
'rampart.sfs_ipban_expiration',
null,
30
); /* # of days to ban */
if ($threshold > 0) {
/**
* If the IP of the spammer shows up past our threshold
* of frequency times that StopForumSpam reports as,
* add a single-ip ban for a certain amount of time
*/
$ipResult = $sfspam->check($result[RampartBase::IP]);
if (!empty($ipResult)) {
$ips = $sfspam->responseXml;
$frequency = (int)$ips->frequency;
if ($frequency >= $threshold) {
$result[RampartBase::STATUS] = RampartBase::STATUS_BANNED;
$result[RampartBase::REASON] = 'sfsip';
$result[RampartBase::DESCRIPTION] = 'StopForumSpam IP Ban';
$result[RampartBase::EXPIRATION] = $expiration;
$result[RampartBase::SERVICE] = 'stopforumspam';
}
}
}
}
}
return $result;
}
public function runProjectHoneyPotChecks(array $result) : array
{
if (empty($this->honey)) {
if (!$this->modx->loadClass('projecthoneypot.RampartHoneyPot', $this->config['modelPath'], true, true)) {
$this->modx->log(
\modX::LOG_LEVEL_ERROR,
'[Rampart] Could not load RampartHoneyPot class from: '.$this->config['modelPath']
);
return $result;
}
$this->honey = new HoneyPot($this);
}
if (!$this->honey->check()) {
$result['response'] = $this->honey->values;
$result[RampartBase::STATUS] = RampartBase::STATUS_BANNED;
$result[RampartBase::SERVICE] = 'projecthoneypot';
$result[RampartBase::REASON] = 'Suspicious';
$result[RampartBase::MATCH_FIELDS] = array(RampartBase::MATCH_IP => $result[RampartBase::IP]);
if (!empty($this->honey->values['comment_spammer'])) {
$result[RampartBase::REASON] = 'HoneyPot: Comment Spammer';
} elseif (!empty($this->honey->values['harvester'])) {
$result[RampartBase::REASON] = 'HoneyPot: Harvester';
}
$result[RampartBase::EXPIRATION] = $this->modx->getOption(
'rampart.honeypot.ban_expiration',
$this->config,
30
);
}
return $result;
}

/**
* Check to see if an IP is on the WhiteList
*
* @param array $result
* @return bool True if found on the WhiteList
*/
public function checkWhiteList(array $result = array()) : bool
{
$c = $this->modx->newQuery('rptWhiteList');
$c->where(array(
'ip' => $result[RampartBase::IP],
'active' => true,
));
$count = $this->modx->getCount('rptWhiteList', $c);
return $count > 0;
}
/**
* Add a ban to the banlist
*
* @param array $result
* @return boolean
*
*/
public function addBan(array $result = array()) : bool
{
if (empty($result[RampartBase::EXPIRATION])) {
$result[RampartBase::EXPIRATION] = 30;
}

/* if specifying an existing ban */
if (!empty($result[RampartBase::BAN])) {
$ban = $this->modx->getObject('rptBan', $result[RampartBase::BAN]);
}
/* otherwise we'll try and grab it from the IP */
if (empty($ban)) {
$ban = $this->modx->getObject('rptBan', array(
'ip' => $result[RampartBase::IP],
));
}
/* and finally, if no matches, create a new ban */
if (empty($ban)) {
$ban = $this->modx->newObject('rptBan');
$ban->set('createdon', time());
$ban->set('active', true);
$boomIp = explode('.', $result[RampartBase::IP]);
$ban->set('ip_low1', $boomIp[0]);
$ban->set('ip_high1', $boomIp[0]);
$ban->set('ip_low2', $boomIp[1]);
$ban->set('ip_high2', $boomIp[1]);
$ban->set('ip_low3', $boomIp[2]);
$ban->set('ip_high3', $boomIp[2]);
$ban->set('ip_low4', $boomIp[3]);
$ban->set('ip_high4', $boomIp[3]);
$ban->set('matches', 1);
$future = time() + ($result[RampartBase::EXPIRATION] * 24 * 60 * 60);
$ban->set('expireson', $future);
} else {
$matches = (int)$ban->get('matches') + 1;
$ban->set('matches', $matches);
}

/* now update IP, last active, store latest data, etc */
if (!empty($result[RampartBase::REASON])) {
$ban->set('reason', $result[RampartBase::REASON]);
}
$ban->set('ip', $result[RampartBase::IP]);
$lastActive = time();
$ban->set('last_activity', $lastActive);
$ban->set('data', $result);
$ban->set('service', !empty($result[RampartBase::SERVICE]) ? $result[RampartBase::SERVICE] : 'manual');
if ($ban->save()) {
/* now create match record */
$match = $this->modx->newObject('rptBanMatch');
$match->set('ban', $ban->get('id'));
$match->set('ip', $result[RampartBase::IP]);
$match->set('hostname', !empty($result[RampartBase::HOSTNAME]) ? $result[RampartBase::HOSTNAME] : '');

$username = !empty($result[RampartBase::USERNAME]) ?
$result[RampartBase::USERNAME] : $this->modx->user->get('username');
$match->set('username', $username);
$match->set('email', !empty($result[RampartBase::EMAIL]) ? $result[RampartBase::EMAIL] : '');
$match->set('useragent', !empty($result[RampartBase::USER_AGENT]) ? $result[RampartBase::USER_AGENT] : '');

if (!empty($result[RampartBase::MATCH_FIELDS])) {
$fields = is_array($result[RampartBase::MATCH_FIELDS]) ?
$result[RampartBase::MATCH_FIELDS] : explode(',', $result[RampartBase::MATCH_FIELDS]);
} else {
$fields = array();
}
if (!empty($fields['ip'])) {
$match->set('ip_match', $fields['ip']);
}
if (!empty($fields['username'])) {
$match->set('username_match', $fields['username']);
}
if (!empty($fields['hostname'])) {
$match->set('hostname_match', $fields['hostname']);
}
if (!empty($fields['email'])) {
$match->set('email_match', $fields['email']);
}

$match->set('resource', ($this->modx->resource) ? $this->modx->resource->get('id') : 0);
$match->set('data', $result);
$match->set('service', !empty($result[RampartBase::SERVICE]) ? $result[RampartBase::SERVICE] : 'manual');
$match->set('notes', !empty($result[RampartBase::NOTES]) ? $result[RampartBase::NOTES] : '');
$match->set('createdon', time());
$match->set('reason', !empty($result[RampartBase::REASON]) ? $result[RampartBase::REASON] : '');

if ($match->save()) {
/* if any field matches, store here */
foreach ($fields as $field => $value) {
$bmf = $this->modx->newObject('rptBanMatchField');
$bmf->set('ban', $ban->get('id'));
$bmf->set('ban_match', $match->get('id'));
$bmf->set('field', $field);
$bmf->save();
}
}
}
return true;
}
}
9 changes: 6 additions & 3 deletions core/components/rampart/src/Processors/Ban/Duplicate.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace Rampart\Processors\Ban;

class Duplicate extends \MODX\Revolution\Processors\ModelProcessor
use MODX\Revolution\Processors\ModelProcessor;
use Rampart\Model\Ban;

class Duplicate extends ModelProcessor
{
public $classKey = \Rampart\Model\Ban::class;
public $classKey = Ban::class;
public $objectType = 'rampart.ban';
public $languageTopics = array('rampart:default');

Expand All @@ -23,7 +26,7 @@ public function initialize()

public function process()
{
/** @var rptBan $newBan */
/** @var Ban $newBan */
$newBan = $this->modx->newObject($this->classKey);
$newBan->fromArray($this->object->toArray());
$newBan->set('editedon', null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace Rampart\Processors\WhiteList;

class Duplicate extends \MODX\Revolution\Processors\ModelProcessor
use MODX\Revolution\Processors\ModelProcessor;
use Rampart\Model\WhiteList;

class Duplicate extends ModelProcessor
{
public $classKey = \Rampart\Model\WhiteList::class;
public $classKey = WhiteList::class;
public $objectType = 'rampart.whitelist';
public $languageTopics = array('rampart:default');

Expand All @@ -23,7 +26,7 @@ public function initialize()

public function process()
{
/** @var rptWhiteList $newWhiteList */
/** @var WhiteList $newWhiteList */
$newWhiteList = $this->modx->newObject($this->classKey);
$newWhiteList->fromArray($this->object->toArray());
$newWhiteList->set('editedon', null);
Expand Down
Loading

0 comments on commit bf50d0a

Please sign in to comment.