From b4f1b9acf65f9e782d56602e60c58be6145c5cca Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 21:28:46 -0700 Subject: Guard against unauthorized agent deletes. --- .../EntityTransfer/EntityTransferModule.cs | 14 ++++++------ .../Simulation/LocalSimulationConnector.cs | 4 ++-- .../Simulation/RemoteSimulationConnector.cs | 6 ++--- OpenSim/Region/Framework/Scenes/Scene.cs | 26 +++++++++++++++++----- .../Framework/Scenes/SceneCommunicationService.cs | 8 +++---- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++++- .../Server/Handlers/Simulation/AgentHandlers.cs | 16 ++++++++----- .../Simulation/SimulationServiceConnector.cs | 7 +++--- OpenSim/Services/Interfaces/ISimulationService.cs | 2 +- 9 files changed, 57 insertions(+), 32 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 85d26f3..ef2ed4f 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -817,7 +817,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); + Fail(sp, finalDestination, logout, Util.Md5Hash(currentAgentCircuit.Id0), "Connection between viewer and destination region could not be established."); return; } @@ -829,7 +829,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); - CleanupFailedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, Util.Md5Hash(currentAgentCircuit.Id0), finalDestination); return; } @@ -873,7 +873,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); + Fail(sp, finalDestination, logout, Util.Md5Hash(currentAgentCircuit.Id0), "Destination region did not signal teleport completion."); return; } @@ -927,7 +927,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) + protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination) { m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); @@ -938,7 +938,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, kill the agent we just created at the destination. // XXX: Possibly this should be done asynchronously. - Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); + Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); } /// @@ -948,9 +948,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// Human readable reason for teleport failure. Will be sent to client. - protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) + protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason) { - CleanupFailedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination); m_interRegionTeleportFailures.Value++; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 2dc3d2a..6d5039b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -286,7 +286,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_token) { if (destination == null) return false; @@ -297,7 +297,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // s.RegionInfo.RegionName, destination.RegionHandle); - m_scenes[destination.RegionID].IncomingCloseAgent(id, false); + m_scenes[destination.RegionID].IncomingCloseAgent(id, false, auth_token); return true; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 4aa2d2a..8722b80 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -245,18 +245,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation } - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_token) { if (destination == null) return false; // Try local first - if (m_localBackend.CloseAgent(destination, id)) + if (m_localBackend.CloseAgent(destination, id, auth_token)) return true; // else do the remote thing if (!m_localBackend.IsLocalRegion(destination.RegionID)) - return m_remoteConnector.CloseAgent(destination, id); + return m_remoteConnector.CloseAgent(destination, id, auth_token); return false; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 54956ee..becea1f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3452,7 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes regions.Remove(RegionInfo.RegionHandle); // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. - m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); + m_sceneGridService.SendCloseChildAgentConnections(agentID, Util.Md5Hash(acd.Id0), regions); } m_eventManager.TriggerClientClosed(agentID, this); @@ -4277,6 +4277,25 @@ namespace OpenSim.Region.Framework.Scenes return false; } + /// + /// Authenticated close (via network) + /// + /// + /// + /// + /// + public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token) + { + //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token); + + // Check that the auth_token is valid + AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); + if (acd != null && Util.Md5Hash(acd.Id0) == auth_token) + return IncomingCloseAgent(agentID, force); + else + m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token); + return false; + } /// /// Tell a single agent to disconnect from the region. @@ -4292,12 +4311,9 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); if (presence != null) - { presence.ControllingClient.Close(force); - return true; - } - // Agent not here + // Agent not here return false; } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 8238e23..77889fa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Closes a child agent on a given region /// - protected void SendCloseChildAgent(UUID agentID, ulong regionHandle) + protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token) { // let's do our best, but there's not much we can do if the neighbour doesn't accept. @@ -210,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName); - m_scene.SimulationService.CloseAgent(destination, agentID); + m_scene.SimulationService.CloseAgent(destination, agentID, auth_token); } /// @@ -219,14 +219,14 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void SendCloseChildAgentConnections(UUID agentID, List regionslst) + public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List regionslst) { foreach (ulong handle in regionslst) { // We must take a copy here since handle is acts like a reference when used in an iterator. // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. ulong handleCopy = handle; - Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy); }); + Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 11b15a7..5991a34 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3167,7 +3167,11 @@ namespace OpenSim.Region.Framework.Scenes { m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); - m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); + AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID); + string auth = string.Empty; + if (acd != null) + auth = Util.Md5Hash(acd.Id0); + m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); } foreach (ulong handle in byebyeRegions) diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 17a8ef4..cd172e4 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -27,11 +27,13 @@ using System; using System.Collections; +using System.Collections.Specialized; using System.IO; using System.IO.Compression; using System.Reflection; using System.Net; using System.Text; +using System.Web; using OpenSim.Server.Base; using OpenSim.Server.Handlers.Base; @@ -92,7 +94,11 @@ namespace OpenSim.Server.Handlers.Simulation string method = (string)request["http-method"]; if (method.Equals("DELETE")) { - DoAgentDelete(request, responsedata, agentID, action, regionID); + string auth_token = string.Empty; + if (request.ContainsKey("auth")) + auth_token = request["auth"].ToString(); + + DoAgentDelete(request, responsedata, agentID, action, regionID, auth_token); return responsedata; } else if (method.Equals("QUERYACCESS")) @@ -151,9 +157,9 @@ namespace OpenSim.Server.Handlers.Simulation // Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); } - protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID) + protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID, string auth_token) { - m_log.Debug(" >>> DoDelete action:" + action + "; RegionID:" + regionID); + m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE action: {0}; RegionID: {1}; from: {2}; auth_code: {3}", action, regionID, Util.GetCallerIP(request), auth_token); GridRegion destination = new GridRegion(); destination.RegionID = regionID; @@ -161,12 +167,12 @@ namespace OpenSim.Server.Handlers.Simulation if (action.Equals("release")) ReleaseAgent(regionID, id); else - Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id); }); + Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id, auth_token); }); responsedata["int_response_code"] = HttpStatusCode.OK; responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); - m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); + //m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); } protected virtual void ReleaseAgent(UUID regionID, UUID id) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 7eb8c24..aca414b 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -367,11 +367,10 @@ namespace OpenSim.Services.Connectors.Simulation /// /// - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_code) { -// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent start"); - - string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; + string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/?auth=" + auth_code; + m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent {0}", uri); try { diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index c9cbd1a..1c82b3e 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -93,7 +93,7 @@ namespace OpenSim.Services.Interfaces /// /// /// - bool CloseAgent(GridRegion destination, UUID id); + bool CloseAgent(GridRegion destination, UUID id, string auth_token); #endregion Agents -- cgit v1.1