From 0413d052a3ec541164049e7d39278c57fb92ed06 Mon Sep 17 00:00:00 2001 From: diva Date: Tue, 14 Apr 2009 19:35:35 +0000 Subject: Adds session authentication upon NewUserConnections. Adds user key authentication (in safemode only) upon CreateChildAgents. All of this for Hypergrid users too. This addresses assorted spoofing vulnerabilities. --- .../Communications/REST/RESTInterregionComms.cs | 79 +++++++++++++++++++++- .../Hypergrid/HGStandaloneInventoryModule.cs | 2 +- .../Hypergrid/HGStandaloneLoginModule.cs | 3 +- 3 files changed, 81 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs index 87272a1..97ffeae 100644 --- a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs +++ b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs @@ -59,6 +59,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST protected RegionToRegionClient m_regionClient; + protected bool m_safemode; + protected IPAddress m_thisIP; + #region IRegionModule public virtual void Initialise(Scene scene, IConfigSource config) @@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST { m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module"); m_enabled = true; + if (config.Configs["Hypergrid"] != null) + m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false); + InitOnce(scene); } } @@ -117,6 +123,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST m_commsManager = scene.CommsManager; m_aScene = scene; m_regionClient = new RegionToRegionClient(m_aScene); + m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); } protected virtual void AddHTTPHandlers() @@ -148,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST { m_regionClient.SendUserInformation(regInfo, aCircuit); - return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit); + return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None"); } //else // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); @@ -331,6 +338,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST responsedata["content_type"] = "text/html"; responsedata["keepalive"] = false; + UUID agentID; string action; ulong regionHandle; @@ -378,6 +386,28 @@ namespace OpenSim.Region.CoreModules.Communications.REST protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) { + if (m_safemode) + { + // Authentication + string authority = string.Empty; + string authToken = string.Empty; + if (!GetAuthentication(request, out authority, out authToken)) + { + m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); + responsedata["int_response_code"] = 403; + responsedata["str_response_string"] = "Forbidden"; + return ; + } + if (!VerifyKey(id, authority, authToken)) + { + m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); + responsedata["int_response_code"] = 403; + responsedata["str_response_string"] = "Forbidden"; + return ; + } + m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id); + } + OSDMap args = RegionClient.GetOSDMap((string)request["body"]); if (args == null) { @@ -793,6 +823,53 @@ namespace OpenSim.Region.CoreModules.Communications.REST } } + public static bool GetAuthentication(Hashtable request, out string authority, out string authKey) + { + authority = string.Empty; + authKey = string.Empty; + + Uri authUri; + Hashtable headers = (Hashtable)request["headers"]; + + // Authorization keys look like this: + // http://orgrid.org:8002/ + if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None") + { + if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri)) + { + authority = authUri.Authority; + authKey = authUri.PathAndQuery.Trim('/'); + m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey); + return true; + } + else + m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]); + } + else + m_log.Debug("[REST COMMS]: Authorization header not found"); + + return false; + } + + bool VerifyKey(UUID userID, string authority, string key) + { + string[] parts = authority.Split(':'); + IPAddress ipaddr = IPAddress.None; + uint port = 0; + if (parts.Length <= 2) + ipaddr = Util.GetHostFromDNS(parts[0]); + if (parts.Length == 2) + UInt32.TryParse(parts[1], out port); + + // local authority (standalone), local call + if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port)) + return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key); + // remote call + else + return AuthClient.VerifyKey("http://" + authority, userID, key); + } + + #endregion Misc protected class RegionToRegionClient : RegionClient diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs index 3675583..f0d70a7 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs @@ -93,7 +93,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid m_inventoryService = new HGInventoryService(m_inventoryBase, ((AssetServerBase)m_scene.CommsManager.AssetCache.AssetServer).AssetProviderPlugin, - (UserManagerBase)m_scene.CommsManager.UserService, m_scene.CommsManager.HttpServer, + (UserManagerBase)m_scene.CommsManager.UserAdminService, m_scene.CommsManager.HttpServer, m_scene.CommsManager.NetworkServersInfo.InventoryURL); AddHttpHandlers(m_scene.CommsManager.HttpServer); diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs index f0e957b..c458b89 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs @@ -104,11 +104,12 @@ namespace OpenSim.Region.CoreModules.Hypergrid IHttpServer httpServer = m_firstScene.CommsManager.HttpServer; //TODO: fix the casting of the user service, maybe by registering the userManagerBase with scenes, or refactoring so we just need a IUserService reference - m_loginService = new HGLoginAuthService((UserManagerBase)m_firstScene.CommsManager.UserService, welcomeMessage, m_firstScene.CommsManager.InterServiceInventoryService, m_firstScene.CommsManager.NetworkServersInfo, authenticate, rootFolder, this); + m_loginService = new HGLoginAuthService((UserManagerBase)m_firstScene.CommsManager.UserAdminService, welcomeMessage, m_firstScene.CommsManager.InterServiceInventoryService, m_firstScene.CommsManager.NetworkServersInfo, authenticate, rootFolder, this); httpServer.AddXmlRPCHandler("hg_login", m_loginService.XmlRpcLoginMethod); httpServer.AddXmlRPCHandler("hg_new_auth_key", m_loginService.XmlRpcGenerateKeyMethod); httpServer.AddXmlRPCHandler("hg_verify_auth_key", m_loginService.XmlRpcVerifyKeyMethod); + httpServer.AddXmlRPCHandler("check_auth_session", m_loginService.XmlRPCCheckAuthSession); } } -- cgit v1.1