function check_ip($rules, $ip) { if (empty($rules) or empty($ip)) { return false; } // do not ckeck $ip = ip2long($ip); if (!$ip) { return false; } if (is_string($rules)) { // : separated rules like as '192.168.0.2:192.167.:...' $rules = explode(':', $rules); } if (!is_array($rules)) { return false; } foreach ($rules as $rule) { $ret = normalize_network($rule); if (!$ret) { continue; } // ignore $network = $ret[0]; $netmask = $ret[1]; if (is_numeric($netmask)) { $netmask = 0xffffffff << 32 - $netmask; } else { $netmask = ip2long($netmask); } $network = ip2long($network); if (($ip & $netmask) == ($network & $netmask)) { return true; } else { if (empty($netmask) and $ip == $network) { return true; } } } return false; }
function do_ipinfo($formatter, $params = array()) { global $DBInfo, $Config; $u = $DBInfo->user; $list = ''; $myip = ''; $mask = 24; $masks = array(24, 25, 16, 18, 8); $ttls = array(1800 => '30 minutes', 3600 => '1 hour', 7200 => '2 hours', 10800 => '3 hours', 21600 => '6 hours', 43200 => '12 hours', 1 => '1 day', 2 => '2 days', 7 => '7 days', 30 => '1 month', 60 => '2 month', 182 => '6 month', 365 => '1 year'); $reasons = array(100 => _("Vandalism"), 150 => _("Abusing"), 200 => _("Incompatible License"), 210 => _("CCL BY"), 220 => _("CCL NC"), 300 => _("Discussion needed"), 400 => _("Robot"), 500 => _("Testing")); if (!empty($params['q'])) { $tmp = normalize_network($params['q']); $myip = $params['q']; if ($tmp === false) { $params['msg'] = sprintf(_("Invalid IP Address %s"), $ip); $params['q'] = ''; } else { $myip = $params['q'] = $ip = $tmp[0]; if ($tmp[1] != 32) { $netmask = $tmp[1]; } } } $control_action = false; if (!empty($params['q']) && isset($_POST) && !empty($params['button_block'])) { $control_action = 'block'; } else { if (!empty($params['q']) && !empty($params['toggle'])) { $control_action = 'toggle'; $params['ttl'] = -1; // HACK to toggle block staus } else { if (!empty($params['q']) && !empty($params['remove'])) { if (in_array($u->id, $DBInfo->owners)) { $control_action = 'remove'; } else { $control_action = 'reset'; } $params['ttl'] = -1; // HACK } } } while ($u->is_member && $control_action !== false) { // check parameters // TTL check if (!empty($params['reason']) and array_key_exists($params['reason'], $reasons)) { $reason = $params['reason']; } if (!empty($params['comment'])) { $comment = $params['comment']; } $ttl = !empty($params['ttl']) ? (int) $params['ttl'] : 1800; // default 30 minutes if (in_array($u->id, $DBInfo->owners)) { $ttl = !empty($params['ttl']) ? $params['ttl'] : 0; // default for owners } else { if ($ttl >= 60) { $ttl = 1800; } } if ($ttl < 0) { $ttl = 1; } else { if ($ttl <= 365) { // days to seconds $ttl = $ttl * 60 * 60 * 24; } } if ($ttl >= 0 && !in_array($u->id, $DBInfo->owners)) { if (empty($comment) && empty($reason)) { $params['msg'] = _("Please select block reason"); break; } } $netmask = !empty($params['netmask']) ? (int) $params['netmask'] : $netmask; if ($netmask >= 32) { $netmask = ''; } $try = $ip; if (!empty($netmask)) { $try .= '/' . $netmask; } $tmp = normalize_network($try); if ($tmp === false) { if (empty($netmask)) { $params['msg'] = sprintf(_("Not a valid IP address: %s"), $try); } else { $params['msg'] = sprintf(_("Not a valid IP range: %s"), $try); } } else { // prepare to return $ret = array(); $retval = array(); $ret['retval'] =& $retval; if ($tmp[1] == 32) { // normalized IP $ip = $tmp[0]; // abusefilter cache $arena = 'abusefilter'; $ac = new Cache_Text('abusefilter'); // fetch monitor information $info = $ac->fetch($ip, 0, $ret); if ($info === false) { $new_info = array('create' => 0, 'delete' => 0, 'revert' => 0, 'save' => 0, 'edit' => 0, 'add_lines' => 0, 'del_lines' => 0, 'add_chars' => 0, 'del_chars' => 0); $new_info['id'] = $ip; $new_info['suspended'] = true; } else { $new_info = $info; $new_info['id'] = $ip; } } else { // normalized IP $ip = $tmp[0] . '/' . $tmp[1]; // ipblock cache $arena = 'ipblock'; $ac = new Cache_Text('ipblock'); // fetch monitor information $info = $ac->fetch($ip, 0, $ret); if ($info === false) { $new_info['id'] = $ip; $new_info['suspended'] = true; } else { $new_info = $info; $new_info['id'] = $ip; } } if (!empty($reason)) { $new_info['reason'] = $reason; } if (!empty($comment)) { // upate comments $comments = array(); if (!empty($info['comment'])) { $comments = explode("\n", $new_info['comment']); } $comments[] = date('Y-m-d H:i', time()) . "\t" . $u->id . "\t" . $comment; if (sizeof($comments) > 100) { array_shift($comments); } $new_info['comment'] = implode("\n", $comments); } if ($ttl == 1) { if ($control_action == 'reset') { $new_info['suspended'] = false; } else { if ($control_action == 'toggle') { $new_info['suspended'] = !$new_info['suspended']; } } $newttl = $retval['ttl'] - (time() - $retval['mtime']); if ($newttl < 0) { $newttl = 0; } if ($control_action == 'remove') { $ac->remove($ip); } else { $ac->update($ip, $new_info, $newttl); } } else { $new_info['suspended'] = true; $ac->update($ip, $new_info, $ttl); } if ($control_action == 'toggle') { $params['msg'] = sprintf(_("Successfully Toggle Block status: %s"), $try); } else { if ($control_action == 'reset') { $params['msg'] = sprintf(_("Successfully Enable IP (range) status: %s"), $try); } else { if ($control_action == 'remove') { $params['msg'] = sprintf(_("Successfully Removed IP range: %s"), $try); } else { if (!empty($netmask)) { $params['msg'] = sprintf(_("Successfully Blocked IP range: %s"), $try); } else { $params['msg'] = sprintf(_("Successfully Blocked IP address: %s"), $try); } } } } } break; } if (!empty($params['q']) && empty($params['button_block'])) { // search $retval = array(); $ret = array('retval' => &$retval); $try = $params['q']; $cache = 'abusefilter'; if (!empty($netmask)) { $try .= '/' . $netmask; $cache = 'ipblock'; } // try to find blocked IP or IP range $ac = new Cache_Text($cache); $info = $ac->fetch($try, 0, $ret); if ($info === false) { // get temporary blocked IP ranges $blocked = get_cached_temporary_blacklist(); $res = search_network($blocked, $params['q'], $ret); $permenant = false; if ($res === false) { // search blacklist ranges $res = search_network($Config['ruleset']['blacklist.ranges'], $params['q'], $ret); $permenant = true; } if ($res) { list($network, $netmask) = explode('/', $retval); if ($netmask == 32) { $title = _("Temporary blocked IP (range) found") . ' : ' . $network; } else { $found = $retval; if ($permenant) { $title = _("Permenantly blocked IP range found") . ' : ' . $found; // show all temporary blocked list $list = macro_IpInfo($formatter); } else { $title = _("Temporary blocked IP range found") . ' : ' . $found; // retrieve found $ac = new Cache_Text('ipblock'); $info = $ac->fetch($found, 0, $ret); if ($info !== false) { $info['ttl'] = $retval['ttl']; $info['mtime'] = $retval['mtime']; $list = macro_IpInfo($formatter, '', array('info' => $info)); } } } } else { $title = _("IP (range) is not found"); // show all temporary blocked list $list = macro_IpInfo($formatter); } } else { $info['ttl'] = $retval['ttl']; $info['mtime'] = $retval['mtime']; $list = macro_IpInfo($formatter, '', array('info' => $info)); $title = _("Temporary blocked IP found") . ' : ' . $params['q']; } } else { if ($u->is_member) { $opt = 'range'; if (!empty($params['static'])) { $opt = 'static'; } if (!empty($params['all'])) { $opt = ''; } $list = macro_IpInfo($formatter, $opt); } else { if (!$u->is_member) { $myip = $params['q'] = $_SERVER['REMOTE_ADDR']; } } } $params['.title'] = _("IP Information"); if (!empty($title)) { $params['title'] = $title; } else { if (!empty($params['q'])) { $params['title'] = sprintf(_("%s: IP Information"), $params['q']); } } $formatter->send_header('', $params); $formatter->send_title($title, '', $params); $searchform = <<<FORM <form method='post' action=''> <label>Search</label>: <input type='text' name='q' value='{$myip}' placeholder='IP or IP range' /> <input type='submit' name='button_search' value='search' /><br /> <input type='hidden' name='action' value='ipinfo' /> </form> FORM; echo '<h2>' . _("Temporary blocked IPs") . '</h2>', "\n"; echo $searchform; echo $list; echo $searchform; echo '<h2>' . _("Input IP or IP range") . '</h2>', "\n"; $mask_select = '<select name="netmask"><option value="">-- ' . _("Netmask") . ' --</option>' . "\n"; foreach ($masks as $m) { $selected = ''; if ($m == $netmask) { $selected = ' selected="selected"'; } $mask_select .= '<option value="' . $m . '"' . $selected . '>' . "\n"; $mask_select .= $m . ' : '; $c = 1 << 32 - $m; if ($c > 1) { $c -= 2; } $mask_select .= number_format($c) . ' IPs'; $mask_select .= '</option>' . "\n"; } $mask_select .= '</select>' . "\n"; $ttl_select = '<select name="ttl"><option value="0">-- ' . _("Expire") . ' --</option>' . "\n"; foreach ($ttls as $time => $str) { $ttl_select .= '<option value="' . $time . '">' . $str . '</option>' . "\n"; } $ttl_select .= '</select>' . "\n"; $reason_select = '<select name="reason"><option value="">-- ' . _("Block reason") . ' --</option>' . "\n"; foreach ($reasons as $code => $str) { $reason_select .= '<option value="' . $code . '">' . $str . '</option>' . "\n"; } $reason_select .= '</select>' . "\n"; $ip_lab = _("IP Address"); $net_lab = _("Netmask (i.e. 24)"); $ttl_lab = _("Expire"); $block_btn = _("Block IP"); echo <<<FORM <form method='post' action=''> <table class='wiki'><tr><th>{$ip_lab}</th> <th>{$net_lab}</th> <th>{$ttl_lab}</th> </tr> <tr> <td><input type='text' name='q' value='{$myip}' /></td> <td> {$mask_select} </td> <td> {$ttl_select} </td> </tr> <tr><td>{$reason_select}</td><td colspan='2'><input type='text' name='comment' size='50' /></td></tr> </table> FORM; echo <<<FORM <input type='hidden' name='action' value='ipinfo' /> <input type='submit' name='button_block' value='{$block_btn}' /> </form> FORM; $formatter->send_footer('', $params); }
function get_acl_group($user, $group = '') { if (empty($group)) { $group = '@[^\\s]+'; } $groups = array(); $gpriority = array(); // group priorities $ip_info = array(); // ip address based info if ($user != 'Anonymous') { $groups[] = '@User'; } else { $this->acl_ip_info($ip_info); } // has acl ip address info ? if (!empty($ip_info)) { $myip = ip2long($_SERVER['REMOTE_ADDR']); $mygrp = array(); $rules = array_keys($ip_info); foreach ($rules as $rule) { $ret = normalize_network($rule, true); if (!$ret) { continue; } // ignore $network = $ret[0]; $netmask = $ret[1]; if (($myip & $netmask) == ($network & $netmask)) { $mygrp = array_merge($mygrp, $ip_info[$rule]); } else { if ($myip == $network) { $mygrp = array_merge($mygrp, $ip_info[$rule]); } } } // group found ? if (!empty($mygrp)) { $groups = array_merge($groups, $mygrp); } } $matches = preg_grep('/^(' . $group . ')\\s+/', $this->AUTH_ACL); foreach ($matches as $line) { list($grp, $tmp) = preg_split('/\\s+/', $line, 2); $tmp = preg_replace("/\\s*,\\s*/", ",", $tmp); // trim spaces: ' , ' => ',' $tmp = rtrim($tmp); list($users, $priority) = preg_split("/\\s+/", $tmp, 2); if (preg_match("/(^|.*,){$user}(,.*|\$)/", $users)) { $groups[] = $grp; } if (!empty($priority) and is_numeric($priority)) { $gpriority[$grp] = $priority; } else { $gpriority[$grp] = 2; } # default group priority } $this->gpriority = $gpriority; return $groups; }
/** * make searchable network ranges for search_network() * * @author Won-Kyu Park <wkpark at gmail.com> * @since 2015/10/05 */ function make_ip_ranges($rules) { $ips = array(); foreach ($rules as $ip) { $ip = trim($ip); $l = false; if (strpos($ip, '/') === false) { $l = ip2long($ip); } if ($l === false) { $tmp = normalize_network($ip, true, true); if ($tmp === false) { // ignore continue; } $ips[$tmp[0]] = $tmp[1]; continue; } $l = sprintf("%u", $l); $ips[$l] = 0; } ksort($ips); $from = array_keys($ips); $to = array_values($ips); return array($from, $to); }
function get_acl($action = 'read', &$options) { if (in_array($options['id'], $this->allowed_users)) { return 1; } $pg = $options['page']; $user = $options['id']; $groups = array(); $groups[] = '@ALL'; $ip_info = array(); // ip address based info if ($user != 'Anonymous') { $groups[] = '@User'; } else { $this->acl_ip_info($ip_info); } // has acl ip address info ? if (!empty($ip_info)) { $myip = ip2long($_SERVER['REMOTE_ADDR']); $mygrp = array(); $rules = array_keys($ip_info); foreach ($rules as $rule) { $ret = normalize_network($rule); if (!$ret) { continue; } // ignore $network = $ret[0]; $netmask = $ret[1]; #print $network . '/' . $netmask . "\n"; if (is_int($netmask)) { $netmask = 0xffffffff << 32 - $netmask; } else { $netmask = ip2long($netmask); } $network = ip2long($network); if (($myip & $netmask) == ($network & $netmask)) { $mygrp = array_merge($mygrp, $ip_info[$rule]); } else { if ($myip == $network) { $mygrp = array_merge($mygrp, $ip_info[$rule]); } } } // group found ? if (!empty($mygrp)) { $groups = array_merge($groups, $mygrp); } } $groups[] = $user; $allowed = array(); $denied = array(); $protected = array(); $gpriority = array(); # group priorities #get group info. $matches = preg_grep('/^(@[^\\s]+)\\s+(.*,?' . $user . ',?.*)/', $this->AUTH_ACL); foreach ($matches as $line) { $grp = preg_split('/\\s+/', $line); $groups[] = $grp[0]; if ($grp[2]) { $gpriority[$grp[0]] = $grp[2]; } else { $gpriority[$grp[0]] = 2; } # default group priority } $gregex = implode('|', $groups); #get ACL info. #$matches= preg_grep('/^('.$pg.'|\*)\s+('.$gregex.')\s+/', $this->AUTH_ACL); $matches = preg_grep('/^[^#@].*\\s+(' . $gregex . ')\\s+/', $this->AUTH_ACL); if (count($matches)) { foreach ($matches as $rule) { #if (in_array($rule[0],array('@','#'))) continue; $rule = preg_replace('/#.*$/', '', $rule); # delete comments $rule = rtrim($rule); $tmp = preg_match('/^(.*)\\s+(' . $gregex . ')\\s+(allow|protect|deny)\\s*(.*)?$/i', $rule, $acl); if (!$tmp) { continue; } if (!$acl[4]) { $acl[4] = '*'; } if ($acl[1] != '*' and $acl[1] != $pg) { $prules = get_csv($acl[1]); // a regex or a simplified pattern like as // HelpOn* -> HelpOn.* // MoniWiki/* -> MoniWiki\/.* $found = false; foreach ($prules as $prule) { if ($prule == $pg) { $found = true; break; } else { $pre = '^'; $post = '$'; if ($prule[0] == '^') { $pre = ''; } if (substr($prule, -1) == '$') { $post = ''; } // is it a regex or a simplified pattern $prule = preg_replace(array('/(?:\\.)?\\*/', "/(?<!\\\\)\\//"), array('.*', '\\/'), $prule); if (@preg_match("/{$pre}{$prule}{$post}/", $pg)) { $found = true; break; } } } if (!$found) { continue; } } if ($acl[3] == 'allow') { $tmp = explode(',', $acl[4]); $tmp = array_flip($tmp); if ($acl[2] == $user) { $pri = 4; } else { if ($acl[2] == '@ALL') { $pri = 1; } else { $pri = !empty($gpriority[$acl[2]]) ? $gpriority[$acl[2]] : 2; } } # get group prio $keys = array_keys($tmp); foreach ($keys as $t) { if (isset($allowed[$t]) and $allowed[$t] > $pri) { unset($tmp[$t]); } else { $tmp[$t] = $pri; } if (isset($denied[$t]) and $denied[$t] <= $pri) { unset($denied[$t]); } } $allowed = array_merge($allowed, $tmp); } else { if ($acl[3] == 'deny') { $tmp = explode(',', $acl[4]); $tmp = array_flip($tmp); if ($acl[2] == $user) { $pri = 4; } else { if ($acl[2] == '@ALL') { $pri = 1; } else { $pri = $gpriority[$acl[2]] ? $gpriority[$acl[2]] : 2; } } # set group prio $keys = array_keys($tmp); foreach ($keys as $t) { if (isset($denied[$t]) and $denied[$t] > $pri) { unset($tmp[$t]); } else { $tmp[$t] = $pri; } if (isset($allowed[$t]) and $allowed[$t] <= $pri) { unset($allowed[$t]); } } $denied = array_merge($denied, $tmp); } else { if ($acl[3] == 'protect') { $tmp = explode(',', $acl[4]); $tmp = array_flip($tmp); $protected = array_merge($protected, $tmp); } } } } } $protected = array_keys($protected); if (!empty($this->DB->acl_debug)) { ob_start(); print "<h4>" . _("ACL groups") . "</h4>\n"; print implode(',', $groups); print "\n"; print "<h4>" . _("Allowed ACL actions") . "</h4>\n"; foreach ($allowed as $k => $v) { print $k . " ({$v}),"; } #print_r($allowed); print "\n"; print "<h4>" . _("Denied ACL actions") . "</h4>\n"; foreach ($denied as $k => $v) { print $k . " ({$v}),"; } #print_r($denied); print "\n"; print "<h4>" . _("Protected ACL actions") . "</h4>\n"; print implode(',', $protected); $options['msg'] .= ob_get_contents(); ob_end_clean(); } $this->_acl_ok = 1; $this->_allowed = $allowed; $this->_denied = $denied; $this->_protected = $protected; return array($allowed, $denied, $protected); }