Finalized the client's TCP IP address verification process for HG1.5.

soprefactor
Diva Canto 2010-05-15 19:25:14 -07:00
parent 4b755c6d80
commit 2a1e45f657
11 changed files with 148 additions and 45 deletions

View File

@ -36,6 +36,7 @@ namespace OpenSim.Framework
public class AgentCircuitManager
{
public Dictionary<uint, AgentCircuitData> AgentCircuits = new Dictionary<uint, AgentCircuitData>();
public Dictionary<UUID, AgentCircuitData> AgentCircuitsByUUID = new Dictionary<UUID, AgentCircuitData>();
public virtual AuthenticateResponse AuthenticateSession(UUID sessionID, UUID agentID, uint circuitcode)
{
@ -86,10 +87,12 @@ namespace OpenSim.Framework
if (AgentCircuits.ContainsKey(circuitCode))
{
AgentCircuits[circuitCode] = agentData;
AgentCircuitsByUUID[agentData.AgentID] = agentData;
}
else
{
AgentCircuits.Add(circuitCode, agentData);
AgentCircuitsByUUID.Add(agentData.AgentID, agentData);
}
}
}
@ -99,10 +102,26 @@ namespace OpenSim.Framework
lock (AgentCircuits)
{
if (AgentCircuits.ContainsKey(circuitCode))
{
UUID agentID = AgentCircuits[circuitCode].AgentID;
AgentCircuits.Remove(circuitCode);
AgentCircuitsByUUID.Remove(agentID);
}
}
}
public virtual void RemoveCircuit(UUID agentID)
{
lock (AgentCircuits)
{
if (AgentCircuitsByUUID.ContainsKey(agentID))
{
uint circuitCode = AgentCircuitsByUUID[agentID].circuitcode;
AgentCircuits.Remove(circuitCode);
AgentCircuitsByUUID.Remove(agentID);
}
}
}
public AgentCircuitData GetAgentCircuitData(uint circuitCode)
{
AgentCircuitData agentCircuit = null;
@ -110,6 +129,13 @@ namespace OpenSim.Framework
return agentCircuit;
}
public AgentCircuitData GetAgentCircuitData(UUID agentID)
{
AgentCircuitData agentCircuit = null;
AgentCircuitsByUUID.TryGetValue(agentID, out agentCircuit);
return agentCircuit;
}
public void UpdateAgentData(AgentCircuitData agentData)
{
if (AgentCircuits.ContainsKey((uint) agentData.circuitcode))

View File

@ -99,6 +99,7 @@ namespace OpenSim.Framework.Capabilities
// private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
//private string eventQueue = "0100/";
private IScene m_Scene;
private IHttpServer m_httpListener;
private UUID m_agentID;
private IAssetService m_assetCache;
@ -130,9 +131,10 @@ namespace OpenSim.Framework.Capabilities
public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
public GetClientDelegate GetClient = null;
public Caps(IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
public Caps(IScene scene, IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
UUID agent, bool dumpAssetsToFile, string regionName)
{
m_Scene = scene;
m_assetCache = assetCache;
m_capsObjectPath = capsPath;
m_httpListener = httpServer;
@ -278,7 +280,13 @@ namespace OpenSim.Framework.Capabilities
public string CapsRequest(string request, string path, string param,
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
//m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
if (!m_Scene.CheckClient(m_agentID, httpRequest.RemoteIPEndPoint))
{
m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
return string.Empty;
}
string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails);

View File

@ -102,5 +102,7 @@ namespace OpenSim.Framework
void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback);
ISceneObject DeserializeObject(string representation);
bool CheckClient(UUID agentID, System.Net.IPEndPoint ep);
}
}

View File

@ -107,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
}
Caps caps
= new Caps(
= new Caps(m_scene,
m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
MainServer.Instance.Port,
capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName);

View File

@ -2629,34 +2629,23 @@ namespace OpenSim.Region.Framework.Scenes
AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
// Do the verification here
System.Net.EndPoint ep = client.GetClientEP();
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)client.GetClientEP();
if (aCircuit != null)
{
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
if (!VerifyClient(aCircuit, ep, out vialogin))
{
m_log.DebugFormat("[Scene]: Incoming client {0} {1} in region {2} via Login", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
vialogin = true;
IUserAgentVerificationModule userVerification = RequestModuleInterface<IUserAgentVerificationModule>();
if (userVerification != null && ep != null)
// uh-oh, this is fishy
m_log.WarnFormat("[Scene]: Agent {0} with session {1} connecting with unidentified end point {2}. Refusing service.",
client.AgentId, client.SessionId, ep.ToString());
try
{
if (!userVerification.VerifyClient(aCircuit, ep.ToString()))
{
// uh-oh, this is fishy
m_log.WarnFormat("[Scene]: Agent {0} with session {1} connecting with unidentified end point {2}. Refusing service.",
client.AgentId, client.SessionId, ep.ToString());
try
{
client.Close();
}
catch (Exception e)
{
m_log.DebugFormat("[Scene]: Exception while closing aborted client: {0}", e.StackTrace);
}
return;
}
else
m_log.DebugFormat("[Scene]: User Client Verification for {0} {1} returned true", aCircuit.firstname, aCircuit.lastname);
client.Close();
}
catch (Exception e)
{
m_log.DebugFormat("[Scene]: Exception while closing aborted client: {0}", e.StackTrace);
}
return;
}
}
@ -2682,7 +2671,65 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerOnClientLogin(client);
}
private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
{
vialogin = false;
// Do the verification here
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
{
m_log.DebugFormat("[Scene]: Incoming client {0} {1} in region {2} via Login", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
vialogin = true;
IUserAgentVerificationModule userVerification = RequestModuleInterface<IUserAgentVerificationModule>();
if (userVerification != null && ep != null)
{
if (!userVerification.VerifyClient(aCircuit, ep.Address.ToString()))
{
// uh-oh, this is fishy
m_log.DebugFormat("[Scene]: User Client Verification for {0} {1} in {2} returned false", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
return false;
}
else
m_log.DebugFormat("[Scene]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
}
}
return true;
}
// Called by Caps, on the first HTTP contact from the client
public override bool CheckClient(UUID agentID, System.Net.IPEndPoint ep)
{
AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(agentID);
if (aCircuit != null)
{
bool vialogin = false;
if (!VerifyClient(aCircuit, ep, out vialogin))
{
// if it doesn't pass, we remove the agentcircuitdata altogether
// and the scene presence and the client, if they exist
try
{
ScenePresence sp = GetScenePresence(agentID);
if (sp != null)
sp.ControllingClient.Close();
// BANG! SLASH!
m_authenticateHandler.RemoveCircuit(agentID);
return false;
}
catch (Exception e)
{
m_log.DebugFormat("[Scene]: Exception while closing aborted client: {0}", e.StackTrace);
}
}
else
return true;
}
return false;
}
/// <summary>
/// Register for events from the client

View File

@ -536,5 +536,6 @@ namespace OpenSim.Region.Framework.Scenes
get { return false; }
}
public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep);
}
}

View File

@ -70,6 +70,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
{
throw new NotImplementedException();
}
public override bool CheckClient(UUID agentID, System.Net.IPEndPoint ep)
{
throw new NotImplementedException();
}
}
[Test]

View File

@ -204,6 +204,11 @@ namespace OpenSim.Services.Connectors.Hypergrid
return args;
}
public void SetClientToken(UUID sessionID, string token)
{
// no-op
}
public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
{
position = Vector3.UnitY; lookAt = Vector3.UnitY;

View File

@ -148,6 +148,15 @@ namespace OpenSim.Services.HypergridService
return true;
}
public void SetClientToken(UUID sessionID, string token)
{
if (m_TravelingAgents.ContainsKey(sessionID))
{
m_log.DebugFormat("[USER AGENT SERVICE]: Setting token {0} for session {1}", token, sessionID);
m_TravelingAgents[sessionID].ClientToken = token;
}
}
TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region)
{
TravelingAgentInfo travel = new TravelingAgentInfo();
@ -203,22 +212,16 @@ namespace OpenSim.Services.HypergridService
public bool VerifyClient(UUID sessionID, string token)
{
return true;
m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token);
//return true;
// Commenting this for now until I understand better what part of a sender's
// info stays unchanged throughout a session
//
//if (m_TravelingAgents.ContainsKey(sessionID))
//{
// // Aquiles heel. Must trust the first grid upon login
// if (m_TravelingAgents[sessionID].ClientToken == string.Empty)
// {
// m_TravelingAgents[sessionID].ClientToken = token;
// return true;
// }
// return m_TravelingAgents[sessionID].ClientToken == token;
//}
//return false;
if (m_TravelingAgents.ContainsKey(sessionID))
return m_TravelingAgents[sessionID].ClientToken == token;
return false;
}
public bool VerifyAgent(UUID sessionID, string token)

View File

@ -49,6 +49,7 @@ namespace OpenSim.Services.Interfaces
public interface IUserAgentService
{
bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
void SetClientToken(UUID sessionID, string token);
void LogoutAgent(UUID userID, UUID sessionID);
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);

View File

@ -329,7 +329,7 @@ namespace OpenSim.Services.LLLoginService
// Instantiate/get the simulation interface and launch an agent at the destination
//
string reason = string.Empty;
AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, out where, out reason);
AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, clientIP, out where, out reason);
if (aCircuit == null)
{
@ -589,7 +589,7 @@ namespace OpenSim.Services.LLLoginService
}
protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar,
UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, out string where, out string reason)
UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, IPEndPoint clientIP, out string where, out string reason)
{
where = currentWhere;
ISimulationService simConnector = null;
@ -655,7 +655,7 @@ namespace OpenSim.Services.LLLoginService
{
circuitCode = (uint)Util.RandomClass.Next(); ;
aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer);
success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, out reason);
success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, clientIP, out reason);
if (!success && m_GridService != null)
{
// Try the fallback regions
@ -664,7 +664,7 @@ namespace OpenSim.Services.LLLoginService
{
foreach (GridRegion r in fallbacks)
{
success = LaunchAgentIndirectly(gatekeeper, r, aCircuit, out reason);
success = LaunchAgentIndirectly(gatekeeper, r, aCircuit, clientIP, out reason);
if (success)
{
where = "safe";
@ -741,10 +741,15 @@ namespace OpenSim.Services.LLLoginService
return simConnector.CreateAgent(region, aCircuit, (int)Constants.TeleportFlags.ViaLogin, out reason);
}
private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, out string reason)
private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason)
{
m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason);
if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason))
{
m_UserAgentService.SetClientToken(aCircuit.SessionID, clientIP.Address.ToString());
return true;
}
return false;
}
#region Console Commands