From 75e8798c1832068173e074b347a73fe244b48610 Mon Sep 17 00:00:00 2001 From: asayre Date: Sat, 10 Feb 2007 08:21:13 +0000 Subject: [PATCH] CIDR's actually working would be nice. That's what I get for assuming the output from a different func would be correct. When banning checked accounts, it should only tag and comment the checked ones, not all of them in the list. Optimizing firewall. --- Scripts/Accounting/Firewall.cs | 249 +++++++++++++++++++++++++--- Scripts/Engines/Pathing/Movement.cs | 9 +- Scripts/Gumps/AdminGump.cs | 5 +- Server/Utility.cs | 40 ++--- 4 files changed, 254 insertions(+), 49 deletions(-) diff --git a/Scripts/Accounting/Firewall.cs b/Scripts/Accounting/Firewall.cs index b982f248a..30e97e546 100644 --- a/Scripts/Accounting/Firewall.cs +++ b/Scripts/Accounting/Firewall.cs @@ -2,16 +2,168 @@ using System; using System.Collections; using System.IO; using System.Net; +using System.Collections.Generic; namespace Server { public class Firewall { - private static ArrayList m_Blocked; + #region Firewall Entries + public interface IFirewallEntry + { + bool IsBlocked( IPAddress address ); + } + + public class IPFirewallEntry : IFirewallEntry + { + IPAddress m_Address; + public IPFirewallEntry( IPAddress address ) + { + m_Address = address; + } + + public bool IsBlocked( IPAddress address ) + { + return m_Address.Equals( address ); + } + + public override string ToString() + { + return m_Address.ToString(); + } + + public override bool Equals( object obj ) + { + if( obj is IPAddress ) + { + return obj.Equals( m_Address ); + } + else if( obj is string ) + { + IPAddress otherAddress; + + if( IPAddress.TryParse( (string)obj, out otherAddress ) ) + return otherAddress.Equals( m_Address ); + } + else if( obj is IPFirewallEntry ) + { + return m_Address.Equals( ((IPFirewallEntry)obj).m_Address ); + } + + return false; + } + + public override int GetHashCode() + { + return m_Address.GetHashCode(); + } + } + + public class CIDRFirewallEntry : IFirewallEntry + { + IPAddress m_CIDRPrefix; + int m_CIDRLength; + + public CIDRFirewallEntry( IPAddress cidrPrefix, int cidrLength ) + { + m_CIDRPrefix = cidrPrefix; + m_CIDRLength = cidrLength; + } + + public bool IsBlocked( IPAddress address ) + { + return Utility.IPMatchCIDR( m_CIDRPrefix, address, m_CIDRLength ); + } + + public override string ToString() + { + return String.Format( "{0}/{1}", m_CIDRPrefix, m_CIDRLength ); + } + + public override bool Equals( object obj ) + { + + if( obj is string ) + { + string entry= (string)obj; + + string[] str = entry.Split( '/' ); + + if( str.Length == 2 ) + { + IPAddress cidrPrefix; + + if( IPAddress.TryParse( str[0], out cidrPrefix ) ) + { + int cidrLength; + + if( int.TryParse( str[1], out cidrLength ) ) + return m_CIDRPrefix.Equals( cidrPrefix ) && m_CIDRLength.Equals( cidrLength ); + } + } + } + else if( obj is CIDRFirewallEntry ) + { + CIDRFirewallEntry entry = obj as CIDRFirewallEntry; + + return m_CIDRPrefix.Equals( entry.m_CIDRPrefix ) && m_CIDRLength.Equals( entry.m_CIDRLength ); + } + + return false; + } + + public override int GetHashCode() + { + return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode(); + } + } + + public class WildcardIPFirewallEntry : IFirewallEntry + { + string m_Entry; + + bool m_Valid = true; + + public WildcardIPFirewallEntry( string entry ) + { + m_Entry = entry; + } + + public bool IsBlocked( IPAddress address ) + { + if( !m_Valid ) + return false; //Why process if it's invalid? it'll return false anyway after processing it. + + return Utility.IPMatch( m_Entry, address, ref m_Valid ); + } + + public override string ToString() + { + return m_Entry.ToString(); + } + + public override bool Equals( object obj ) + { + if( obj is string ) + return obj.Equals( m_Entry ); + else if( obj is WildcardIPFirewallEntry ) + m_Entry.Equals( ((WildcardIPFirewallEntry)obj).m_Entry ); + + return false; + } + + public override int GetHashCode() + { + return m_Entry.GetHashCode(); + } + } + #endregion + + private static List m_Blocked; static Firewall() { - m_Blocked = new ArrayList(); + m_Blocked = new List(); string path = "firewall.cfg"; @@ -28,6 +180,9 @@ namespace Server if ( line.Length == 0 ) continue; + m_Blocked.Add( ToFirewallEntry( line ) ); + + /* object toAdd; IPAddress addr; @@ -37,12 +192,13 @@ namespace Server toAdd = line; m_Blocked.Add( toAdd.ToString() ); + * */ } } } } - public static ArrayList List + public static List List { get { @@ -50,47 +206,87 @@ namespace Server } } + public static IFirewallEntry ToFirewallEntry( object entry ) + { + if( entry is IFirewallEntry ) + return (IFirewallEntry)entry; + else if( entry is IPAddress ) + return new IPFirewallEntry( (IPAddress)entry ); + else if( entry is string ) + return ToFirewallEntry( (string)entry ); + + return null; + } + + public static IFirewallEntry ToFirewallEntry( string entry ) + { + IPAddress addr; + + if( IPAddress.TryParse( entry, out addr ) ) + return new IPFirewallEntry( addr ); + + + + //Try CIDR parse + string[] str = entry.Split( '/' ); + + if( str.Length == 2 ) + { + IPAddress cidrPrefix; + + if( IPAddress.TryParse( str[0], out cidrPrefix ) ) + { + int cidrLength; + + if( int.TryParse( str[1], out cidrLength ) ) + return new CIDRFirewallEntry( cidrPrefix, cidrLength ); + } + } + + return new WildcardIPFirewallEntry( entry ); + } + public static void RemoveAt( int index ) { m_Blocked.RemoveAt( index ); Save(); } - public static void Remove( string pattern ) + public static void Remove( object obj ) { - m_Blocked.Remove( pattern ); - Save(); - } + IFirewallEntry entry = ToFirewallEntry( obj ); - public static void Remove( IPAddress ip ) - { - m_Blocked.Remove( ip ); - Save(); + if( entry != null ) + { + m_Blocked.Remove( entry ); + Save(); + } } public static void Add( object obj ) { - if ( !(obj is IPAddress) && !(obj is String) ) - return; - - if ( !m_Blocked.Contains( obj ) ) - m_Blocked.Add( obj ); - - Save(); + if( obj is IPAddress ) + Add( (IPAddress)obj ); + else if( obj is string ) + Add( (string)obj ); } public static void Add( string pattern ) { - if ( !m_Blocked.Contains( pattern ) ) - m_Blocked.Add( pattern ); + IFirewallEntry entry = ToFirewallEntry( pattern ); + + if( !m_Blocked.Contains( entry ) ) + m_Blocked.Add( entry ); Save(); } public static void Add( IPAddress ip ) { - if ( !m_Blocked.Contains( ip ) ) - m_Blocked.Add( ip ); + IFirewallEntry entry = new IPFirewallEntry( ip ); + + if( !m_Blocked.Contains( entry ) ) + m_Blocked.Add( entry ); Save(); } @@ -108,6 +304,14 @@ namespace Server public static bool IsBlocked( IPAddress ip ) { + for( int i = 0; i < m_Blocked.Count; i++ ) + { + if( m_Blocked[i].IsBlocked( ip ) ) + return true; + } + + return false; + /* bool contains = false; for ( int i = 0; !contains && i < m_Blocked.Count; ++i ) @@ -126,6 +330,7 @@ namespace Server } return contains; + * */ } } } \ No newline at end of file diff --git a/Scripts/Engines/Pathing/Movement.cs b/Scripts/Engines/Pathing/Movement.cs index d1744932a..6bdf663e5 100644 --- a/Scripts/Engines/Pathing/Movement.cs +++ b/Scripts/Engines/Pathing/Movement.cs @@ -85,9 +85,9 @@ namespace Server.Movement bool landBlocks = (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Impassable) != 0; bool considerLand = !landTile.Ignored; - if ( landBlocks && canSwim && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) != 0 ) + if ( landBlocks && canSwim && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) != 0 ) //Impassable, Can Swim, and Is water. Don't block it. landBlocks = false; - else if ( cantWalk && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == 0 ) + else if ( cantWalk && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == 0 ) //Can't walk and it's not water landBlocks = true; int landZ = 0, landCenter = 0, landTop = 0; @@ -101,6 +101,7 @@ namespace Server.Movement bool ignoreDoors = ( m_AlwaysIgnoreDoors || !m.Alive || m.Body.BodyID == 0x3DB || m.IsDeadBondedPet ); + #region Tiles for ( int i = 0; i < tiles.Length; ++i ) { Tile tile = tiles[i]; @@ -152,7 +153,9 @@ namespace Server.Movement } } } + #endregion + #region Items for ( int i = 0; i < items.Count; ++i ) { Item item = items[i]; @@ -205,6 +208,8 @@ namespace Server.Movement } } + #endregion + if ( considerLand && !landBlocks && stepTop >= landZ ) { int ourZ = landCenter; diff --git a/Scripts/Gumps/AdminGump.cs b/Scripts/Gumps/AdminGump.cs index 54e4b35eb..8651e6fd9 100644 --- a/Scripts/Gumps/AdminGump.cs +++ b/Scripts/Gumps/AdminGump.cs @@ -1545,7 +1545,7 @@ namespace Server.Gumps from.SendGump( new NoticeGump( 1060637, 30720, String.Format( "You have {0} the account{1}.", ban ? "banned" : "deleted", rads.Count == 1 ? "" : "s" ), 0xFFC000, 420, 280, new NoticeGumpCallback( ResendGump_Callback ), new object[]{ list, rads, ban ? page : 0 } ) ); if ( ban ) - from.SendGump( new BanDurationGump( list ) ); + from.SendGump( new BanDurationGump( rads ) ); } else { @@ -2503,8 +2503,7 @@ namespace Server.Gumps { CommandLogging.WriteLine( from, "{0} {1} removing {2} from firewall list", from.AccessLevel, CommandLogging.Format( from ), m_State ); - Firewall.List.Remove( m_State ); - Firewall.Save(); + Firewall.Remove( m_State ); from.SendGump( new AdminGump( from, AdminGumpPage.Firewall, 0, null, String.Format( "{0} : Removed from firewall.", m_State ), null ) ); } diff --git a/Server/Utility.cs b/Server/Utility.cs index e131d1ebd..3b6741f18 100644 --- a/Server/Utility.cs +++ b/Server/Utility.cs @@ -128,7 +128,7 @@ namespace Server { string[] str = cidr.Split( '/' ); - if ( str.Length < 2 ) + if ( str.Length != 2 ) return false; IPAddress cidrPrefix; @@ -151,12 +151,26 @@ namespace Server uint mask = uint.MaxValue << cidrLength; - long cidrValue = Utility.GetLongAddressValue( cidrPrefix ); - long ipValue = Utility.GetLongAddressValue( ip ); + uint cidrValue = Utility.OrderedAddressValue( cidrPrefix ); + uint ipValue = Utility.OrderedAddressValue( ip ); return ( ( cidrValue & mask ) == ( ipValue & mask ) ); } + private static uint OrderedAddressValue( IPAddress address ) + { + uint value = 0; + + byte[] bytes = address.GetAddressBytes(); + + for( int i=0; i < bytes.Length; i++ ) + { + value |= ((uint)bytes[i]) << (bytes.Length-1 -i)*8; + } + + return value; + } + public static bool IPMatch( string val, IPAddress ip, ref bool valid ) { valid = true; @@ -256,7 +270,7 @@ namespace Server } else { - valid = false; + valid = false; //high & lowpart would be 0 if it got to here. } } } @@ -321,24 +335,6 @@ namespace Server int.TryParse( value, out i ); return i; - - /* - try - { - if ( value.StartsWith( "0x" ) ) - { - return Convert.ToInt32( value.Substring( 2 ), 16 ); - } - else - { - return Convert.ToInt32( value ); - } - } - catch - { - return 0; - } - * */ } #endregion