diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index c9e56e6392..e5f747437d 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -1605,6 +1605,17 @@ namespace OpenSim.Client.MXP.ClientStack return default(T); } + public void Disconnect(string reason) + { + Kick(reason); + Close(true); + } + + public void Disconnect() + { + Close(true); + } + #endregion public void SendCreateGroupReply(UUID groupID, bool success, string message) diff --git a/OpenSim/Framework/Client/IClientCore.cs b/OpenSim/Framework/Client/IClientCore.cs index 78f041121a..1d08fb910f 100644 --- a/OpenSim/Framework/Client/IClientCore.cs +++ b/OpenSim/Framework/Client/IClientCore.cs @@ -25,11 +25,20 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using OpenMetaverse; + namespace OpenSim.Framework.Client { public interface IClientCore { bool TryGet(out T iface); T Get(); + + // Basic Interfaces + UUID AgentId { get; } + + void Disconnect(string reason); + void Disconnect(); + } } \ No newline at end of file diff --git a/OpenSim/Framework/Client/IClientIPEndpoint.cs b/OpenSim/Framework/Client/IClientIPEndpoint.cs new file mode 100644 index 0000000000..b80dea5bed --- /dev/null +++ b/OpenSim/Framework/Client/IClientIPEndpoint.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; + +namespace OpenSim.Framework.Client +{ + public interface IClientIPEndpoint + { + IPAddress EndPoint { get; } + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index f9db91ca18..a157df5811 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Handles new client connections /// Constructor takes a single Packet and authenticates everything /// - public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IStatsCollector + public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -10478,6 +10478,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { RegisterInterface(this); RegisterInterface(this); + RegisterInterface(this); } public bool TryGet(out T iface) @@ -10496,6 +10497,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP return (T)m_clientInterfaces[typeof(T)]; } + public void Disconnect(string reason) + { + Kick(reason); + Thread.Sleep(1000); + Close(true); + } + + public void Disconnect() + { + Close(true); + } + + #endregion private void RefreshGroupMembership() @@ -10587,5 +10601,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP { return ""; } + + #region IClientIPEndpoint Members + + public IPAddress EndPoint + { + get + { + if(m_userEndPoint is IPEndPoint) + { + IPEndPoint ep = (IPEndPoint)m_userEndPoint; + + return ep.Address; + } + return null; + } + } + + #endregion } } diff --git a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs new file mode 100644 index 0000000000..b904cb0fbc --- /dev/null +++ b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Agent.IPBan +{ + public class IPBanModule : IRegionModule + { + #region Implementation of IRegionModule + + private List m_bans = new List(); + + public void Initialise(Scene scene, IConfigSource source) + { + new SceneBanner(scene, m_bans); + + lock(m_bans) + { + foreach (EstateBan ban in scene.RegionInfo.EstateSettings.EstateBans) + { + if(!String.IsNullOrEmpty(ban.BannedHostIPMask)) + m_bans.Add(ban.BannedHostIPMask); + if (!String.IsNullOrEmpty(ban.BannedHostNameMask)) + m_bans.Add(ban.BannedHostNameMask); + } + } + } + + public void PostInitialise() + { + if(File.Exists("bans.txt")) + { + string[] bans = File.ReadAllLines("bans.txt"); + foreach (string ban in bans) + { + m_bans.Add(ban); + } + } + } + + public void Close() + { + + } + + public string Name + { + get { return "IPBanModule"; } + } + + public bool IsSharedModule + { + get { return true; } + } + + #endregion + + /// + /// Bans all users from the specified network from connecting. + /// DNS bans are in the form "somewhere.com" will block ANY + /// matching domain (including "betasomewhere.com", "beta.somewhere.com", + /// "somewhere.com.beta") - make sure to be reasonably specific in DNS + /// bans. + /// + /// IP address bans match on first characters, so, + /// "127.0.0.1" will ban only that address, + /// "127.0.1" will ban "127.0.10.0" + /// but "127.0.1." will ban only the "127.0.1.*" network + /// + /// See summary for explanation of parameter + public void Ban(string host) + { + m_bans.Add(host); + } + } +} diff --git a/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs b/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs new file mode 100644 index 0000000000..1d8da46b68 --- /dev/null +++ b/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.Net; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Agent.IPBan +{ + internal class SceneBanner + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private List bans; + private SceneBase m_scene; + public SceneBanner(SceneBase scene, List banList) + { + scene.EventManager.OnClientConnect += EventManager_OnClientConnect; + + bans = banList; + m_scene = scene; + } + + void EventManager_OnClientConnect(IClientCore client) + { + IClientIPEndpoint ipEndpoint; + if(client.TryGet(out ipEndpoint)) + { + IPAddress end = ipEndpoint.EndPoint; + + IPHostEntry rDNS = Dns.GetHostEntry(end); + foreach (string ban in bans) + { + if (rDNS.HostName.Contains(ban) || + end.ToString().StartsWith(ban)) + { + client.Disconnect("Banned - network \"" + ban + "\" is not allowed to connect to this server."); + m_log.Warn("[IPBAN] Disconnected '" + end + "' due to '" + ban + "' ban."); + return; + } + } + m_log.Warn("[IPBAN] User '" + end + "' not in any ban lists. Allowing connection."); + } + } + } +}