1<?php 2/** 3 * IPGroup Plugin 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Sascha Bendix <sascha.bendix@localroot.de> 7 * @author Marcel Pennewiss <opensource@pennewiss.de> 8 * @author Peter Grosse <pegro@fem-net.de> 9 * @author Jonas Licht <jonas.licht@fem.tu-ilmenau.de> 10 */ 11 12if(!defined('DOKU_INC')) die(); 13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 14 15require_once(DOKU_PLUGIN.'action.php'); 16 17class action_plugin_ipgroup extends DokuWiki_Action_Plugin { 18 19 /** 20 * Register event handlers 21 */ 22 public function register(Doku_Event_Handler $controller) { 23 $controller->register_hook('AUTH_ACL_CHECK', 'BEFORE', $this, 'start'); 24 } 25 26 function start(&$event, $param) { 27 // get remote ip when user is using a proxy 28 $ip = clientIP(true); 29 30 // read config file or create 31 $filecontent = @file(DOKU_CONF.'ipgroup.conf', FILE_SKIP_EMPTY_LINES); 32 if ($filecontent === false) { $filecontent = array(); } 33 34 // check current ip against each network-definition 35 foreach ($filecontent as $line) { 36 // seperate network and group and trim spaces 37 list($network,$group) = explode(';', $line); 38 $network = rtrim($network); 39 $group = rtrim($group); 40 41 // seperate cidr-suffix from network 42 $network_bits = substr($network,strpos($network,'/')+1); 43 44 // only go further if the acces is done via the same ip version then the network we are currently looking at 45 if (filter_var($network_address,FILTER_VALIDATE_IP,FILTER_FLAG_IPV4) == filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_IPV4) 46 || (filter_var($network_address,FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) == filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_IPV6))) { 47 48 // check if ip matches network 49 if ($this->ip2pton($ip."/".$network_bits) === $this->ip2pton($network)) { 50 // add group to list 51 $event->data['groups'][] = $group; 52 } 53 } 54 } 55 } 56 57 /** 58 * calc ip-adress to in_addr-representation 59 * @link http://www.php.net/manual/de/function.inet-pton.php#93501 source and idea 60 */ 61 function ip2pton($ipaddr) { 62 63 // Strip out the netmask, if there is one. 64 $cx = strpos($ipaddr, '/'); 65 if ($cx) 66 { 67 $subnet = (int)(substr($ipaddr, $cx+1)); 68 $ipaddr = substr($ipaddr, 0, $cx); 69 } 70 else $subnet = null; // No netmask present 71 72 // Convert address to packed format 73 $addr = inet_pton($ipaddr); 74 75 // Convert the netmask 76 if (is_integer($subnet)) 77 { 78 // Maximum netmask length = same as packed address 79 $len = 8*strlen($addr); 80 if ($subnet > $len) $subnet = $len; 81 82 // Create a hex expression of the subnet mask 83 $mask = str_repeat('f', $subnet>>2); 84 switch($subnet & 3) 85 { 86 case 3: $mask .= 'e'; break; 87 case 2: $mask .= 'c'; break; 88 case 1: $mask .= '8'; break; 89 } 90 $mask = str_pad($mask, $len>>2, '0'); 91 92 // Packed representation of netmask 93 $mask = pack('H*', $mask); 94 } 95 96 // Return logical and of addr and mask 97 return ($addr & $mask); 98 } 99} 100