diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index b66bfed42f..9385b8df74 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Net; using System.Reflection; +using System.Text.RegularExpressions; using OpenSim.Framework; using OpenSim.Services.Interfaces; @@ -57,6 +58,9 @@ namespace OpenSim.Services.HypergridService private static IUserAgentService m_UserAgentService; private static ISimulationService m_SimulationService; + protected string m_AllowedClients = string.Empty; + protected string m_DeniedClients = string.Empty; + private static UUID m_ScopeID; private static bool m_AllowTeleportsToAnyRegion; private static string m_ExternalName; @@ -104,6 +108,9 @@ namespace OpenSim.Services.HypergridService else if (simulationService != string.Empty) m_SimulationService = ServerUtils.LoadPlugin(simulationService, args); + m_AllowedClients = serverConfig.GetString("AllowedClients", string.Empty); + m_DeniedClients = serverConfig.GetString("DeniedClients", string.Empty); + if (m_GridService == null || m_PresenceService == null || m_SimulationService == null) throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); @@ -181,8 +188,36 @@ namespace OpenSim.Services.HypergridService string authURL = string.Empty; if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) authURL = aCircuit.ServiceURLs["HomeURI"].ToString(); - m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}", - aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName); + m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}", + aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName, + aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0); + + // + // Check client + // + if (m_AllowedClients != string.Empty) + { + Regex arx = new Regex(m_AllowedClients); + Match am = arx.Match(aCircuit.Viewer); + + if (!am.Success) + { + m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", aCircuit.Viewer); + return false; + } + } + + if (m_DeniedClients != string.Empty) + { + Regex drx = new Regex(m_DeniedClients); + Match dm = drx.Match(aCircuit.Viewer); + + if (dm.Success) + { + m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", aCircuit.Viewer); + return false; + } + } // // Authenticate the user diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index d364aa4b9f..9bcc3dd225 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -77,7 +77,11 @@ namespace OpenSim.Services.LLLoginService protected string m_MapTileURL; protected string m_SearchURL; + protected string m_AllowedClients; + protected string m_DeniedClients; + IConfig m_LoginServerConfig; + IConfig m_ClientsConfig; public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService) { @@ -105,7 +109,10 @@ namespace OpenSim.Services.LLLoginService m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); - + + m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); + m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); + // These are required; the others aren't if (accountService == string.Empty || authService == string.Empty) throw new Exception("LoginService is missing service specifications"); @@ -215,10 +222,37 @@ namespace OpenSim.Services.LLLoginService bool success = false; UUID session = UUID.Random(); - m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} from {2} with user agent {3} starting in {4}", - firstName, lastName, clientIP.Address.ToString(), clientVersion, startLocation); + m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}", + firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0); try { + // + // Check client + // + if (m_AllowedClients != string.Empty) + { + Regex arx = new Regex(m_AllowedClients); + Match am = arx.Match(clientVersion); + + if (!am.Success) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is not allowed", clientVersion); + return LLFailedLoginResponse.LoginBlockedProblem; + } + } + + if (m_DeniedClients != string.Empty) + { + Regex drx = new Regex(m_DeniedClients); + Match dm = drx.Match(clientVersion); + + if (dm.Success) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is denied", clientVersion); + return LLFailedLoginResponse.LoginBlockedProblem; + } + } + // // Get the account and check that it exists // diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index f2f2a66992..572497c0b3 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -197,6 +197,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 SRV_AssetServerURI = "http://127.0.0.1:8002" SRV_ProfileServerURI = "http://127.0.0.1:8002/user" + ;; Regular expressions for controlling which client versions are accepted/denied. + ;; An empty string means nothing is checked. + ;; + ;; Example 1: allow only these 3 types of clients (any version of them) + ;; AllowedClients = "Imprudence|Hippo|Second Life" + ;; + ;; Example 2: allow all clients except these + ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald" + ;; + ;; Note that these are regular expressions, so every character counts. + ;; Also note that this is very weak security and should not be trusted as a reliable means + ;; for keeping bad clients out; modified clients can fake their identifiers. + ;; + ;; + ;AllowedClients = "" + ;DeniedClients = "" + [GridInfoService] ; These settings are used to return information on a get_grid_info call. ; Client launcher scripts and third-party clients make use of this to @@ -256,6 +273,22 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; If you run this gatekeeper server behind a proxy, set this to true ; HasProxy = false + ;; Regular expressions for controlling which client versions are accepted/denied. + ;; An empty string means nothing is checked. + ;; + ;; Example 1: allow only these 3 types of clients (any version of them) + ;; AllowedClients = "Imprudence|Hippo|Second Life" + ;; + ;; Example 2: allow all clients except these + ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald" + ;; + ;; Note that these are regular expressions, so every character counts. + ;; Also note that this is very weak security and should not be trusted as a reliable means + ;; for keeping bad clients out; modified clients can fake their identifiers. + ;; + ;; + ;AllowedClients = "" + ;DeniedClients = "" [UserAgentService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService" diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index aef0596a03..047e9eeed6 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -176,6 +176,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; If you run this login server behind a proxy, set this to true ; HasProxy = false + ;; Regular expressions for controlling which client versions are accepted/denied. + ;; An empty string means nothing is checked. + ;; + ;; Example 1: allow only these 3 types of clients (any version of them) + ;; AllowedClients = "Imprudence|Hippo|Second Life" + ;; + ;; Example 2: allow all clients except these + ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald" + ;; + ;; Note that these are regular expressions, so every character counts. + ;; Also note that this is very weak security and should not be trusted as a reliable means + ;; for keeping bad clients out; modified clients can fake their identifiers. + ;; + ;; + ;AllowedClients = "" + ;DeniedClients = "" + [GridInfoService] ; These settings are used to return information on a get_grid_info call. ; Client launcher scripts and third-party clients make use of this to diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index dcebd63184..67efa11564 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -83,6 +83,23 @@ SRV_AssetServerURI = "http://127.0.0.1:9000" SRV_ProfileServerURI = "http://127.0.0.1:9000" + ;; Regular expressions for controlling which client versions are accepted/denied. + ;; An empty string means nothing is checked. + ;; + ;; Example 1: allow only these 3 types of clients (any version of them) + ;; AllowedClients = "Imprudence|Hippo|Second Life" + ;; + ;; Example 2: allow all clients except these + ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald" + ;; + ;; Note that these are regular expressions, so every character counts. + ;; Also note that this is very weak security and should not be trusted as a reliable means + ;; for keeping bad clients out; modified clients can fake their identifiers. + ;; + ;; + ;AllowedClients = "" + ;DeniedClients = "" + [GatekeeperService] ExternalName = "http://127.0.0.1:9000" @@ -90,6 +107,23 @@ ; If false, HG TPs happen only to the Default regions specified in [GridService] section AllowTeleportsToAnyRegion = true + ;; Regular expressions for controlling which client versions are accepted/denied. + ;; An empty string means nothing is checked. + ;; + ;; Example 1: allow only these 3 types of clients (any version of them) + ;; AllowedClients = "Imprudence|Hippo|Second Life" + ;; + ;; Example 2: allow all clients except these + ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald" + ;; + ;; Note that these are regular expressions, so every character counts. + ;; Also note that this is very weak security and should not be trusted as a reliable means + ;; for keeping bad clients out; modified clients can fake their identifiers. + ;; + ;; + ;AllowedClients = "" + ;DeniedClients = "" + [GridInfoService] ; These settings are used to return information on a get_grid_info call. ; Client launcher scripts and third-party clients make use of this to