# HG changeset patch # User Dan # Date 1189306718 14400 # Node ID 01955bf53f9678f741c6f935f1242a4c19edc081 # Parent a2b20a8324479d6f8347b8e7fa552b0924ead27b Improved ban control page and allowed multiple entries/IP ranges; changed some parameters on jBox; user level changes are logged now diff -r a2b20a832447 -r 01955bf53f96 includes/clientside/static/dropdown.js --- a/includes/clientside/static/dropdown.js Sat Sep 08 15:06:28 2007 -0400 +++ b/includes/clientside/static/dropdown.js Sat Sep 08 22:58:38 2007 -0400 @@ -123,7 +123,7 @@ if(typeof(others[i]) == 'object') { others[i].style.display = 'none'; - others[i].previousSibling.className = ''; + $(others[i].previousSibling).rmClass('liteselected'); } } var others = obj.parentNode.getElementsByTagName('div'); @@ -134,13 +134,14 @@ if ( others[i].className == 'submenu' ) { others[i].style.display = 'none'; - others[i].previousSibling.className = ''; + $(others[i].previousSibling).rmClass('liteselected'); } } } if(obj.nextSibling.tagName.toLowerCase() == 'ul' || ( obj.nextSibling.tagName.toLowerCase() == 'div' && obj.nextSibling.className == 'submenu' )) { - obj.className = 'liteselected'; + $(a).addClass('liteselected'); + //obj.className = 'liteselected'; var ul = obj.nextSibling; var dim = fetch_dimensions(obj); var off = fetch_offset(obj); @@ -197,7 +198,7 @@ if (!isOverObj(a, false, event) && !isOverObj(ul, true, event)) { - a.className = ''; + $(a).rmClass('liteselected'); if ( jBox_slide_enable ) { @@ -399,7 +400,7 @@ { if ( !isOverObj(uls[j], false, e) ) { - uls[j].previousSibling.className = ''; + $(uls[j].previousSibling).rmClass('liteselected'); //uls[j].style.display = 'none'; slideIn(uls[j]); } @@ -412,7 +413,7 @@ { if ( !isOverObj(uls[j], false, e) ) { - uls[j].previousSibling.className = ''; + $(uls[j].previousSibling).rmClass('liteselected'); //uls[j].style.display = 'none'; slideIn(uls[j]); } diff -r a2b20a832447 -r 01955bf53f96 includes/clientside/static/toolbar.js --- a/includes/clientside/static/toolbar.js Sat Sep 08 15:06:28 2007 -0400 +++ b/includes/clientside/static/toolbar.js Sat Sep 08 22:58:38 2007 -0400 @@ -9,7 +9,7 @@ { if(obj.id == 'mdgToolbar_article' || obj.id == 'mdgToolbar_discussion') { - obj.className = ''; + $(obj).rmClass('selected'); } obj = obj.nextSibling; } @@ -22,7 +22,7 @@ obj = document.getElementById('pagebar_main').firstChild.nextSibling; while(obj) { - if ( obj.className != 'selected' ) + if ( !$(obj).hasClass('selected') ) { obj = obj.nextSibling; continue; @@ -30,7 +30,7 @@ if(obj.id != 'mdgToolbar_article' && obj.id != 'mdgToolbar_discussion') { if ( obj.className ) - obj.className = ''; + $(obj).rmClass('selected'); } obj = obj.nextSibling; } @@ -46,7 +46,7 @@ if(typeof(dom) == 'object') { unselectAllButtonsMajor(); - document.getElementById('mdgToolbar_'+which).className = 'selected'; + $('mdgToolbar_'+which).addClass('selected'); } } @@ -57,7 +57,7 @@ if(typeof(document.getElementById('mdgToolbar_'+which)) == 'object') { unselectAllButtonsMinor(); - document.getElementById('mdgToolbar_'+which).className = 'selected'; + $('mdgToolbar_'+which).addClass('selected'); } } diff -r a2b20a832447 -r 01955bf53f96 includes/dbal.php --- a/includes/dbal.php Sat Sep 08 15:06:28 2007 -0400 +++ b/includes/dbal.php Sat Sep 08 22:58:38 2007 -0400 @@ -196,7 +196,7 @@ $quotepos = 0; $prev_is_quote = false; $just_started = false; - for($i=0;$i'; continue; } - $just_entered = false; + $just_started = false; } if(substr(trim($q), strlen(trim($q))-1, 1) == ';') $q = substr(trim($q), 0, strlen(trim($q))-1); for($i=0;$i' . '
' . print_r($match, true) . '
'; + return false; + } return true; } diff -r a2b20a832447 -r 01955bf53f96 includes/functions.php --- a/includes/functions.php Sat Sep 08 15:06:28 2007 -0400 +++ b/includes/functions.php Sat Sep 08 22:58:38 2007 -0400 @@ -2846,6 +2846,85 @@ return $html; } +/** + * For an input range of numbers (like 25-256) returns an array filled with all numbers in the range, inclusive. + * @param string + * @return array + */ + +function int_range($range) +{ + if ( strval(intval($range)) == $range ) + return $range; + if ( !preg_match('/^[0-9]+(-[0-9]+)?$/', $range) ) + return false; + $ends = explode('-', $range); + if ( count($ends) != 2 ) + return $range; + $ret = array(); + if ( $ends[1] < $ends[0] ) + $ends = array($ends[1], $ends[0]); + else if ( $ends[0] == $ends[1] ) + return array($ends[0]); + for ( $i = $ends[0]; $i <= $ends[1]; $i++ ) + { + $ret[] = $i; + } + return $ret; +} + +/** + * Parses a range or series of IP addresses, and returns the raw addresses. Only parses ranges in the last two octets to prevent DOSing. + * Syntax for ranges: x.x.x.x; x|y.x.x.x; x.x.x-z.x; x.x.x-z|p.q|y + * @param string IP address range string + * @return array + */ + +function parse_ip_range($range) +{ + $octets = explode('.', $range); + if ( count($octets) != 4 ) + // invalid range + return $range; + $i = 0; + $possibilities = array( 0 => array(), 1 => array(), 2 => array(), 3 => array() ); + foreach ( $octets as $octet ) + { + $existing =& $possibilities[$i]; + $inner = explode('|', $octet); + foreach ( $inner as $bit ) + { + if ( $i >= 2 ) + { + $bits = int_range($bit); + if ( $bits === false ) + return false; + else if ( !is_array($bits) ) + $existing[] = intval($bits); + else + $existing = array_merge($existing, $bits); + } + else + { + $bit = intval($bit); + $existing[] = $bit; + } + } + $existing = array_unique($existing); + $i++; + } + $ips = array(); + + // The only way to combine all those possibilities. ;-) + foreach ( $possibilities[0] as $oc1 ) + foreach ( $possibilities[1] as $oc2 ) + foreach ( $possibilities[2] as $oc3 ) + foreach ( $possibilities[3] as $oc4 ) + $ips[] = "$oc1.$oc2.$oc3.$oc4"; + + return $ips; +} + //die('
Original:  01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'
'); ?> diff -r a2b20a832447 -r 01955bf53f96 includes/template.php --- a/includes/template.php Sat Sep 08 15:06:28 2007 -0400 +++ b/includes/template.php Sat Sep 08 22:58:38 2007 -0400 @@ -943,7 +943,15 @@ $h = fopen($tpl_filename, 'w'); if(!$h) return $text; $t = addslashes($text); - fwrite($h, ''); + $notice = <<'); fclose($h); } return $text; //('
'.htmlspecialchars($text).'
'); diff -r a2b20a832447 -r 01955bf53f96 plugins/SpecialAdmin.php --- a/plugins/SpecialAdmin.php Sat Sep 08 15:06:28 2007 -0400 +++ b/plugins/SpecialAdmin.php Sat Sep 08 22:58:38 2007 -0400 @@ -860,19 +860,31 @@ // We need to update group memberships if ( $old_level == USER_LEVEL_ADMIN ) { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_from_admin",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($_POST['new_username']) . '");'); + if ( !$q ) + $db->_die(); $session->remove_user_from_group($user_id, GROUP_ID_ADMIN); } else if ( $old_level == USER_LEVEL_MOD ) { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_from_mod",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($_POST['new_username']) . '");'); + if ( !$q ) + $db->_die(); $session->remove_user_from_group($user_id, GROUP_ID_MOD); } if ( $new_level == USER_LEVEL_ADMIN ) { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_to_admin",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($_POST['new_username']) . '");'); + if ( !$q ) + $db->_die(); $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false); } else if ( $new_level == USER_LEVEL_MOD ) { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_to_mod",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($_POST['new_username']) . '");'); + if ( !$q ) + $db->_die(); $session->add_user_to_group($user_id, GROUP_ID_MOD, false); } } @@ -2064,12 +2076,66 @@ } if(isset($_POST['create']) && !defined('ENANO_DEMO_MODE')) { - $q = 'INSERT INTO '.table_prefix.'banlist(ban_type,ban_value,reason,is_regex) VALUES( ' . $db->escape($_POST['type']) . ', \'' . $db->escape($_POST['value']) . '\', \''.$db->escape($_POST['reason']).'\''; - if(isset($_POST['regex'])) $q .= ', 1'; - else $q .= ', 0'; - $q .= ');'; - $e = $db->sql_query($q); - if(!$e) $db->_die('The banlist could not be updated.'); + $type = intval($_POST['type']); + $value = trim($_POST['value']); + if ( !in_array($type, array(BAN_IP, BAN_USER, BAN_EMAIL)) ) + { + echo '
Hacking attempt.
'; + } + else if ( empty($value) ) + { + echo '
Please enter something to ban.
'; + } + else + { + $entries = array(); + $input = explode(',', $_POST['value']); + $error = false; + foreach ( $input as $entry ) + { + $entry = trim($entry); + if ( empty($entry) ) + { + echo '
Malformed entry.
'; + $error = true; + break; + } + if ( $type == BAN_IP ) + { + // parse a range of addresses + $range = parse_ip_range($entry); + if ( !$range ) + { + $error = true; + echo '
Malformed IP address expression.
'; + break; + } + foreach ($range as $ip) + { + $entries[] = $ip; + } + } + else + { + $entries[] = $entry; + } + } + if ( !$error ) + { + $regex = ( isset($_POST['regex']) ) ? '1' : '0'; + $to_insert = array(); + $reason = $db->escape($_POST['reason']); + foreach ( $entries as $entry ) + { + $entry = $db->escape($entry); + $to_insert[] = "($type, '$entry', '$reason', $regex)"; + } + $q = 'INSERT INTO '.table_prefix."banlist(ban_type, ban_value, reason, is_regex)\n VALUES" . implode(",\n ", $to_insert) . ';'; + @set_time_limit(0); + $e = $db->sql_query($q); + if(!$e) $db->_die('The banlist could not be updated.'); + } + } } else if ( isset($_POST['create']) && defined('ENANO_DEMO_MODE') ) { @@ -2077,25 +2143,29 @@ } $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); if(!$q) $db->_die('The banlist data could not be selected.'); - echo ''; + echo '
+
'; echo ''; - if($db->numrows() < 1) echo ''; + if($db->numrows() < 1) echo ''; + $cls = 'row2'; while($r = $db->fetchrow()) { + $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; if($r['ban_type']==BAN_IP) $t = 'IP address'; elseif($r['ban_type']==BAN_USER) $t = 'Username'; elseif($r['ban_type']==BAN_EMAIL) $t = 'E-mail address'; if($r['is_regex']) $g = 'Yes'; else $g = 'No'; - echo ''; + echo ''; } $db->free_result(); - echo '
TypeValueRegular Expression
No ban rules yet.No ban rules yet.
'.$t.''.$r['ban_value'].''.$g.'Delete
'.$t.''.$r['ban_value'].''.$g.'Delete
'; + echo ''; echo '

Create new ban rule

'; echo '
'; ?> Type:
Rule:
- Reason to show to the banned user:
+ You can ban multiple IP addresses, users, or e-mail addresses by separating entries with a single comma (User1,User2). Do not put a space after the comma. For IP addresses, you may specify ranges like 172|192.168.4-30|90-167.1-90, which will turn into 172 and 192 . 168 . 4-30 and 90-167 . 1 - 90, which matches 18,899 IP addresses. Don't specify large ranges (like the example one here) at once or you risk temporarily (~60sec) overloading the server.
+ Reason to show to the banned user:
(advanced users only)
'.date('d M Y h:i a', $r['time_id']).''.$r['author'].''.$r['edit_summary'].''; return $return;