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/Clients/RegionClient.cs | 7 ++-- .../Framework/Communications/IAuthentication.cs | 1 + OpenSim/Framework/Communications/IUserService.cs | 4 ++ .../Communications/Services/LoginService.cs | 46 ++++++++++++++++++++++ .../Communications/Tests/Cache/AssetCacheTests.cs | 5 +++ .../Framework/Communications/UserManagerBase.cs | 15 +++++++ OpenSim/Framework/Util.cs | 16 ++++++++ 7 files changed, 91 insertions(+), 3 deletions(-) (limited to 'OpenSim/Framework') diff --git a/OpenSim/Framework/Communications/Clients/RegionClient.cs b/OpenSim/Framework/Communications/Clients/RegionClient.cs index 27353b0..da3f620 100644 --- a/OpenSim/Framework/Communications/Clients/RegionClient.cs +++ b/OpenSim/Framework/Communications/Clients/RegionClient.cs @@ -43,7 +43,7 @@ namespace OpenSim.Framework.Communications.Clients { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public bool DoCreateChildAgentCall(RegionInfo region, AgentCircuitData aCircuit) + public bool DoCreateChildAgentCall(RegionInfo region, AgentCircuitData aCircuit, string authKey) { // Eventually, we want to use a caps url instead of the agentID string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + aCircuit.AgentID + "/"; @@ -54,6 +54,7 @@ namespace OpenSim.Framework.Communications.Clients AgentCreateRequest.ContentType = "application/json"; AgentCreateRequest.Timeout = 10000; //AgentCreateRequest.KeepAlive = false; + AgentCreateRequest.Headers.Add("Authorization", authKey); // Fill it in OSDMap args = null; @@ -80,7 +81,7 @@ namespace OpenSim.Framework.Communications.Clients } catch (Exception e) { - m_log.WarnFormat("[OSG2]: Exception thrown on serialization of ChildCreate: {0}", e.Message); + m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildCreate: {0}", e.Message); // ignore. buffer will be empty, caller should check. } @@ -91,7 +92,7 @@ namespace OpenSim.Framework.Communications.Clients os = AgentCreateRequest.GetRequestStream(); os.Write(buffer, 0, strBuffer.Length); //Send it os.Close(); - //m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri); + //m_log.InfoFormat("[REST COMMS]: Posted CreateChildAgent request to remote sim {0}", uri); } //catch (WebException ex) catch diff --git a/OpenSim/Framework/Communications/IAuthentication.cs b/OpenSim/Framework/Communications/IAuthentication.cs index 0f62569..bd568e4 100644 --- a/OpenSim/Framework/Communications/IAuthentication.cs +++ b/OpenSim/Framework/Communications/IAuthentication.cs @@ -34,5 +34,6 @@ namespace OpenSim.Framework.Communications { string GetNewKey(string url, UUID userID, UUID authToken); bool VerifyKey(UUID userID, string key); + bool VerifySession(UUID iserID, UUID sessionID); } } diff --git a/OpenSim/Framework/Communications/IUserService.cs b/OpenSim/Framework/Communications/IUserService.cs index 3c09b40..3a56d35 100644 --- a/OpenSim/Framework/Communications/IUserService.cs +++ b/OpenSim/Framework/Communications/IUserService.cs @@ -119,5 +119,9 @@ namespace OpenSim.Framework.Communications /// /// The agent that we're retreiving the friends Data. List GetUserFriendList(UUID friendlistowner); + + // This probably shouldn't be here, it belongs to IAuthentication + // But since Scenes only have IUserService references, I'm placing it here for now. + bool VerifySession(UUID userID, UUID sessionID); } } diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index d9556e4..d491309 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs @@ -37,6 +37,7 @@ using log4net; using Nwc.XmlRpc; using OpenMetaverse; using OpenMetaverse.StructuredData; +using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Statistics; @@ -194,6 +195,12 @@ namespace OpenSim.Framework.Communications.Services CreateAgent(userProfile, request); + // We need to commit the agent right here, even though the userProfile info is not complete + // at this point. There is another commit further down. + // This is for the new sessionID to be stored so that the region can check it for session authentication. + // CustomiseResponse->PrepareLoginToRegion + CommitAgent(ref userProfile); + try { UUID agentID = userProfile.ID; @@ -1108,5 +1115,44 @@ namespace OpenSim.Framework.Communications.Services { return false; } + + public XmlRpcResponse XmlRPCCheckAuthSession(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + string authed = "FALSE"; + if (requestData.Contains("avatar_uuid") && requestData.Contains("session_id")) + { + UUID guess_aid; + UUID guess_sid; + + UUID.TryParse((string)requestData["avatar_uuid"], out guess_aid); + if (guess_aid == UUID.Zero) + { + return Util.CreateUnknownUserErrorResponse(); + } + UUID.TryParse((string)requestData["session_id"], out guess_sid); + if (guess_sid == UUID.Zero) + { + return Util.CreateUnknownUserErrorResponse(); + } + if (m_userManager.VerifySession(guess_aid, guess_sid)) + { + authed = "TRUE"; + } + m_log.InfoFormat("[UserManager]: CheckAuthSession TRUE for user {0}", guess_aid); + } + else + { + m_log.InfoFormat("[UserManager]: CheckAuthSession FALSE"); + return Util.CreateUnknownUserErrorResponse(); + } + Hashtable responseData = new Hashtable(); + responseData["auth_session"] = authed; + response.Value = responseData; + return response; + } + } } diff --git a/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs b/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs index 5d6bc8d..178c356 100644 --- a/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs +++ b/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs @@ -178,6 +178,11 @@ namespace OpenSim.Framework.Communications.Tests { throw new NotImplementedException(); } + + public bool VerifySession(UUID userID, UUID sessionID) + { + return true; + } } [Test] diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs index 155f5cd..1115041 100644 --- a/OpenSim/Framework/Communications/UserManagerBase.cs +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -839,6 +839,21 @@ namespace OpenSim.Framework.Communications } } + public bool VerifySession(UUID userID, UUID sessionID) + { + UserProfileData userProfile = GetUserProfile(userID); + + if (userProfile != null && userProfile.CurrentAgent != null) + { + m_log.DebugFormat("[USERAUTH]: Verifying session {0} for {1}; current session {2}", sessionID, userID, userProfile.CurrentAgent.SessionID); + if (userProfile.CurrentAgent.SessionID == sessionID) + { + return true; + } + } + return false; + } + #endregion } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 7019096..f1993b2 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Data; using System.Globalization; @@ -820,6 +821,21 @@ namespace OpenSim.Framework } /// + /// Returns an error message that the user could not be found in the database + /// + /// XML string consisting of a error element containing individual error(s) + public static XmlRpcResponse CreateUnknownUserErrorResponse() + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + responseData["error_type"] = "unknown_user"; + responseData["error_desc"] = "The user requested is not in the database"; + + response.Value = responseData; + return response; + } + + /// /// Converts a byte array in big endian order into an ulong. /// /// -- cgit v1.1