From: <bla...@us...> - 2008-09-28 20:18:18
|
Revision: 18655 http://bzflag.svn.sourceforge.net/bzflag/?rev=18655&view=rev Author: blast007 Date: 2008-09-28 20:18:12 +0000 (Sun, 28 Sep 2008) Log Message: ----------- Implement the new ban system. Now supports IP bans (exact, CIDR, and wildcard) and hostname bans (exact and wildcard). Modified Paths: -------------- trunk/db/bzfls.php trunk/db/bzflsadmin.php trunk/db/support/database_structure.sql Added Paths: ----------- trunk/db/banfunctions.php Added: trunk/db/banfunctions.php =================================================================== --- trunk/db/banfunctions.php (rev 0) +++ trunk/db/banfunctions.php 2008-09-28 20:18:12 UTC (rev 18655) @@ -0,0 +1,105 @@ +<?php + + // Passing in the following array items for $values + // ipaddress + // hostname + // username or bzid + + function IsBanned($values, $bans) { + foreach($bans as $ban) { + // Only do the check if we have this type of value + if (!isset($values[$ban['type']])) + continue; + + // If we don't have an array for a value, toss it into one + if (!is_array($values[$ban['type']])) + $values[$ban['type']] = Array($values[$ban['type']]); + // If we have an array, make sure we have items or just go to the next ban + else if (sizeof($values[$ban['type']]) == 0) + continue; + + foreach ($values[$ban['type']] as $value) { + + //echo "Checking $value against the ban {$ban['value']}\n"; + + // IP Address + // Supports exact matches, wildcards, and CIDR notation + // Ex: 192.168.0.1 + // 192.168.0.* + // 192.168.*.* + // 192.*.*.* + // 192.168.0.0/24 + if ($ban['type'] == 'ipaddress') { + // Check if the ban has a CIDR + if (strpos($ban['value'], '/') !== false) { + // Split apart the IP and CIDR + list($ip, $cidr) = explode('/', $ban['value']); + + // Do a binary match based on the CIDR value + if (strncmp(sprintf("%032b", ip2long($ip)), sprintf("%032b", ip2long($value)), $cidr) == 0) + return $ban; + } + // Check if the ban has a wildcard + else if (strpos($ban['value'], '*') !== false) { + // Split the values into octets + $banparts = explode('.', $ban['value']); + $parts = explode('.', $value); + + // We need four parts for each + if (sizeof($parts) != 4 || sizeof($banparts) != 4) + continue; + + // Check to see if all of the parts match + for ($i = 0; $i < 4; $i++) + if ($banparts[$i] != '*' && $banparts[$i] != $parts[$i]) + break; + + // If $i is set to 4, that means that the for loop above completed. + // If so, that means that all four octets matched up. + if ($i == 4) + return $ban; + } + else { + // No CIDR or wildcard, so do an exact match + if (ip2long($value) == ip2long($ban['value'])) + return $ban; + } + } + + // Hostname + // Supports exact matches and wildcards + // Ex: example.org + // *.example.org + // some-region*.someisp.com + else if ($ban['type'] == 'hostname') { + // Check if the ban has a wildcard + if (strpos($ban['value'], '*') !== false) { + // We have a wildcard, compare with a regex + if (eregi(str_replace(Array('.', '*'), Array('\.', '(.*)'), $ban['value']), $value)) + return $ban; + } + else { + // No wildcard, so do an exact match + if ($value == $ban['value']) + return $ban; + } + } + + // BZID + // Only supports exact matches + else if ($ban['type'] == 'bzid') { + // Check for an exact match + if ($value == $ban['value']) + return $ban; + } + + } // foreach ($values as $value) + + } // foreach($bans as $ban) + + // No ban matched + return false; + + } // function CheckBan($values, $bans) + +?> Property changes on: trunk/db/banfunctions.php ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Modified: trunk/db/bzfls.php =================================================================== --- trunk/db/bzfls.php 2008-09-28 19:19:37 UTC (rev 18654) +++ trunk/db/bzfls.php 2008-09-28 20:18:12 UTC (rev 18655) @@ -31,6 +31,8 @@ // $dbuname = 'bzflag'; // $dbpass = 'bzflag'; +include('banfunctions.php'); + debug('Connecting to the database', 3); # Connect to the server database persistently. @@ -48,13 +50,10 @@ # ip address. value is not used at present. these are pulled # from the serverbans table. $banlist = array(); -$result = sqlQuery ('SELECT address, owner, reason FROM serverbans ' +$result = sqlQuery ('SELECT type, value, owner, reason FROM serverbans ' . 'WHERE active = 1'); for ($i = 0; $i < mysql_num_rows ($result); ++$i) { - $banlist[mysql_result ($result, $i, 'address')] = - mysql_result ($result, $i, 'owner'). - (mysql_result ($result, $i, 'reason') != '' ? - ': '.mysql_result ($result, $i, 'reason') : '' ); + $banlist[] = mysql_fetch_assoc($result); } // $alternateServers = array('http://my.BZFlag.org/db/',''); @@ -779,8 +778,20 @@ print('See <a href="http://BZFlag.org">http://BZFlag.org</a></body></html>'); } +# set up a list of addresses to check +$values = Array(); +$values['ipaddress'][0] = $_SERVER['REMOTE_ADDR']; +$values['hostname'][0] = gethostbyaddr($_SERVER['REMOTE_ADDR']); + +# If the hostname value came back as an IP, there wasn't a reverse DNS name, +# so ditch it +if ($values['hostname'][0] == $values['ipaddress'][0]) + unset($values['hostname'][0]); + +# TODO: Add a check for the $nameport variable here and add that to $values + # ignore banned servers outright -if ($banlist[$_SERVER['REMOTE_ADDR']] != "") { +if (IsBanned($values, $banlist)) { # reject the connection attempt header('Content-type: text/plain'); $remote_addr = $_SERVER['REMOTE_ADDR']; Modified: trunk/db/bzflsadmin.php =================================================================== --- trunk/db/bzflsadmin.php 2008-09-28 19:19:37 UTC (rev 18654) +++ trunk/db/bzflsadmin.php 2008-09-28 20:18:12 UTC (rev 18655) @@ -140,7 +140,7 @@ <input type="hidden" name="id" value="<?php echo $_POST['id']; ?>"> <table class="listform"> <tr><td>Ban Type:</td><td><select name="type"><option value="ipaddress"<?php if ($data['type'] == 'ipaddress') echo ' selected="selected"'; ?>>IP Address</option><option value="hostname"<?php if ($data['type'] == 'hostname') echo ' selected="selected"'; ?>>Hostname</option></select></td></tr> - <tr><td>IP/Hostname</td><td><input type="text" name="address" value="<?php echo $data['address']; ?>"></td></tr> + <tr><td>IP/Hostname</td><td><input type="text" name="value" value="<?php echo $data['value']; ?>"></td></tr> <tr><td>Owner</td><td><input type="text" name="owner" value="<?php echo $data['owner']; ?>"></td></tr> <tr><td>Reason</td><td><input type="text" name="reason" value="<?php echo $data['reason']; ?>"></td></tr> </table> @@ -161,7 +161,7 @@ } // make sure we have data - if (! $_POST['address']) { + if (! $_POST['value']) { header ("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']); break; @@ -170,17 +170,17 @@ // run update query mysql_select_db ($dbname) or die ("Could not select bzbb database."); if ($_POST['id']) - $sql = sprintf ("UPDATE serverbans SET type = '%s', address = '%s', owner = '%s', reason = '%s', lastby = %u WHERE banid = %u", + $sql = sprintf ("UPDATE serverbans SET type = '%s', value = '%s', owner = '%s', reason = '%s', lastby = %u WHERE banid = %u", mysql_real_escape_string ($_POST['type']), - mysql_real_escape_string ($_POST['address']), + mysql_real_escape_string ($_POST['value']), mysql_real_escape_string ($_POST['owner']), mysql_real_escape_string ($_POST['reason']), $_SESSION['bzid'], $_POST['id']); else - $sql = sprintf ("INSERT INTO serverbans SET type = '%s', address = '%s', owner = '%s', reason = '%s', lastby = %u", + $sql = sprintf ("INSERT INTO serverbans SET type = '%s', value = '%s', owner = '%s', reason = '%s', lastby = %u", mysql_real_escape_string ($_POST['type']), - mysql_real_escape_string ($_POST['address']), + mysql_real_escape_string ($_POST['value']), mysql_real_escape_string ($_POST['owner']), mysql_real_escape_string ($_POST['reason']), $_SESSION['bzid']); @@ -308,7 +308,7 @@ 'id' => $result_array['banid'], 'active' => $result_array['active'], 'type' => $result_array['type'], - 'address' => $result_array['address'], + 'value' => $result_array['value'], 'owner' => $result_array['owner'], 'reason' => $result_array['reason'], 'lastby' => $result_array['lastby'])); @@ -333,7 +333,7 @@ else echo '<td>Unknown</td>'; - echo '<td>'.$ban['address'].'</td>'. + echo '<td>'.$ban['value'].'</td>'. '<td>'.$ban['owner'].'</td>'. '<td>'.$ban['reason'].'</td>'. '<td>'.$ban['lastby'].'</td>'. Modified: trunk/db/support/database_structure.sql =================================================================== --- trunk/db/support/database_structure.sql 2008-09-28 19:19:37 UTC (rev 18654) +++ trunk/db/support/database_structure.sql 2008-09-28 20:18:12 UTC (rev 18655) @@ -123,7 +123,7 @@ CREATE TABLE `serverbans` ( `banid` int(2) NOT NULL auto_increment, `type` varchar(32) NOT NULL, - `address` varchar(64) NOT NULL, + `value` varchar(64) NOT NULL, `owner` varchar(64) default NULL, `reason` varchar(128) default NULL, `lastby` int(2) NOT NULL, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |