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