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.

This commit is contained in:
diva
2009-04-14 19:35:35 +00:00
parent d0744f8eca
commit 0413d052a3
18 changed files with 414 additions and 205 deletions

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -119,5 +119,9 @@ namespace OpenSim.Framework.Communications
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
List<FriendListItem> 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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -178,6 +178,11 @@ namespace OpenSim.Framework.Communications.Tests
{
throw new NotImplementedException();
}
public bool VerifySession(UUID userID, UUID sessionID)
{
return true;
}
}
[Test]

View File

@@ -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
}
}

View File

@@ -26,6 +26,7 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
@@ -819,6 +820,21 @@ namespace OpenSim.Framework
return client.Send(url, 6000);
}
/// <summary>
/// Returns an error message that the user could not be found in the database
/// </summary>
/// <returns>XML string consisting of a error element containing individual error(s)</returns>
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;
}
/// <summary>
/// Converts a byte array in big endian order into an ulong.
/// </summary>