Extension:RequestFilter.php
<php><?php
- Block problem users, bots and requests
$wgExtensionFunctions[] = 'wgRequestFilter'; function wgRequestFilter() { global $wgUser,$wgShortName,$wgRequest;
$filter = '/var/www/filter-rules'; $log = '/var/www/activity.log'; $ts = date('Y-m-d H:i:s'); $types = array('ip','user','session'); # Types are fields containing patterns $head = "{"."{#security:*|admin}"."}{"."{#filesync:$filter}"."}\n{"."{#tree:\n"; $tail = "}"."}\n";
# Request information $url = $_SERVER['REQUEST_URI']; $ip = $_SERVER['REMOTE_ADDR']; $user = $wgUser->isAnon() ? : $wgUser->getUserPage()->getText(); $session = ereg('_session=([0-9a-z]+)',$_SERVER['HTTP_COOKIE'],$m) ? $m[1] : ;
# Read rules file into a hash of rules[ID][TYPE][PATTERN => COMMENT] $rules = array(); $id = ; $type = ; foreach (file($filter) as $line) { if (ereg('^\\*\\s*(\\w+)',$line,$m)) $id = $m[1]; if (eregi('^\\*{2}\\s*(action|user|ip|session)',$line,$m)) $type = strtolower($m[1]); if (ereg('^\\*{3}\\s*([^#]+)(.*)$',$line,$m)) { if (is_array($rules[$id][$type])) $rules[$id][$type][$m[1]] = $m[2]; else $rules[$id][$type] = array($m[1] => $m[2]); } }
# For each pattern that matches its type, add any other types with non-empty values to rules tree # eg. if the request's session matches one of the ID's session-patterns, # then we can add the request's IP and user to that ID if not already present $changed = false; foreach ($rules as $id => $rule) { # Check rules for each ID foreach ($types as $type) { # Check each matchable type in this ID's rules foreach ($rule[$type] as $pattern => $comment) { # Loop through all patterns listed in this type if (preg_match("/$pattern/",$$type)) { # Check if the pattern matches the current request's value of this type foreach($types as $other) { # If so, loop through all other types that have values in the current request if ($other != $type && $$other) { $k = "^$$other$"; if (!in_array($k,$rule[$other])) { # and update the tree with an inferred value $changed = true; $comment = "inferred by $type match ($$type)"; $rule[$other][$k] = " # $ts: $comment"; $entry .= " $other $comment\n"; } } } } } } }
# If tree changed, rebuild and write to file if ($changed) { $tree = ; foreach ($rules as $id => $rule) { $tree .= "*$id\n"; foreach ($rule as $type => $item) { $tree .= "**$type\n"; foreach ($item as $k => $v) { $tree .= is_numeric($k) ? "***$v\n" : "***$k # $v\n"; } } } file_put_contents($filter,"$head$tree$tail"); }
# Write log entry $handle = fopen($log,"a"); # todo: build log entry $entry = "$ts ($wgShortName): $url\n$entry"; fwrite($handle,"$ts ($wgShortName): $url\n");
# Perform actions #if ($block) { sleep(1); die; } }
?> </php>