1<?php 2 3/** 4 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 5 * @author Andreas Gohr <andi@splitbrain.org> 6 */ 7class action_plugin_ipban extends DokuWiki_Action_Plugin 8{ 9 10 /** 11 * register the eventhandlers and initialize some options 12 */ 13 public function register(Doku_Event_Handler $controller) 14 { 15 16 $controller->register_hook('DOKUWIKI_STARTED', 17 'BEFORE', 18 $this, 19 'handle_start', 20 array()); 21 } 22 23 /** 24 * Do the magic 25 * 26 * @param Doku_Event $event 27 * @param $param 28 */ 29 public function handle_start(Doku_Event $event, $param) 30 { 31 global $conf; 32 33 $bans = @file($conf['cachedir'] . '/ipbanplugin.txt'); 34 $client = clientIP(true); 35 if (!is_array($bans)) return; 36 37 // if the client isn't banned, we're done 38 $banreason = $this->isBanned($client, $bans); 39 if (!$banreason) return; 40 41 // prepare template 42 $text = $this->locale_xhtml('banned'); 43 $text .= vsprintf('<p>' . $this->getLang('banned') . '</p>', array_map('hsc', $banreason)); 44 $title = $this->getLang('denied'); 45 46 // output 47 http_status(403, 'Forbidden'); 48 echo '<!DOCTYPE html>'; 49 echo '<html>'; 50 echo "<head><title>$title</title></head>"; 51 echo '<body style="font-family: Arial, sans-serif">'; 52 echo '<div style="width:60%; margin: auto; background-color: #fcc; border: 1px solid #faa; padding: 0.5em 1em;">'; 53 echo $text; 54 echo '</div>'; 55 echo '</body>'; 56 echo '</html>'; 57 exit; 58 } 59 60 /** 61 * Check if the given client IP is in the list of ban lines 62 * 63 * @param string $client IP of the client 64 * @param string[] $banconf List of ban lines 65 * @return false|array false or ban info [ip, date, reason] 66 */ 67 protected function isBanned($client, $banconf) 68 { 69 require_once(__DIR__ . '/ip-lib/ip-lib.php'); 70 71 $ip = \IPLib\Factory::addressFromString($client); 72 foreach ($banconf as $ban) { 73 list($range, $dt, /*user*/, $reason) = explode("\t", trim($ban)); 74 $ipRange = \IPLib\Factory::rangeFromString($range); 75 if($ipRange === null) continue; 76 if ($ip->matches($ipRange)) { 77 return [ 78 $ip->toString(), 79 dformat($dt), 80 $reason, 81 ]; 82 } 83 } 84 85 return false; 86 } 87} 88