From 00f7d622cbc2c2e61d2efaacd8275da3f9821d8b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 28 Jan 2010 19:19:42 -0800 Subject: HG 1.5 is in place. Tested in standalone only. --- OpenSim/Framework/AgentCircuitData.cs | 5 + .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 20 -- .../EntityTransfer/EntityTransferModule.cs | 10 +- .../EntityTransfer/HGEntityTransferModule.cs | 112 ++++--- .../Hypergrid/HypergridServiceInConnectorModule.cs | 4 +- .../Framework/Interfaces/IEntityTransferModule.cs | 5 + OpenSim/Region/Framework/Scenes/Scene.cs | 33 +- OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs | 4 +- .../Hypergrid/GatekeeperServerConnector.cs | 3 +- .../Hypergrid/HomeUsersSecurityServerConnector.cs | 122 ------- .../Server/Handlers/Hypergrid/HypergridHandlers.cs | 33 -- .../Handlers/Hypergrid/UserAgentServerConnector.cs | 168 ++++++++++ .../Hypergrid/GatekeeperServiceConnector.cs | 90 ----- .../Hypergrid/HomeUsersSecurityServiceConnector.cs | 132 -------- .../Hypergrid/UserAgentServiceConnector.cs | 370 +++++++++++++++++++++ .../Simulation/SimulationServiceConnector.cs | 37 ++- .../Services/HypergridService/GatekeeperService.cs | 77 ++--- .../HypergridService/HomeUsersSecurityService.cs | 67 ---- .../Services/HypergridService/UserAgentService.cs | 210 ++++++++++++ OpenSim/Services/Interfaces/IGatekeeperService.cs | 14 +- OpenSim/Services/LLLoginService/LLLoginService.cs | 224 ++++++++++--- 21 files changed, 1100 insertions(+), 640 deletions(-) delete mode 100644 OpenSim/Server/Handlers/Hypergrid/HomeUsersSecurityServerConnector.cs create mode 100644 OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs delete mode 100644 OpenSim/Services/Connectors/Hypergrid/HomeUsersSecurityServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs delete mode 100644 OpenSim/Services/HypergridService/HomeUsersSecurityService.cs create mode 100644 OpenSim/Services/HypergridService/UserAgentService.cs (limited to 'OpenSim') diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 142ca2c..9c9b4b0 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -75,6 +75,11 @@ namespace OpenSim.Framework public uint circuitcode; /// + /// How this agent got here + /// + public uint teleportFlags; + + /// /// Agent's account first name /// public string firstname; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index ffd2546..3c4fa72 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -38,7 +38,6 @@ using OpenMetaverse.Packets; using OpenSim.Framework; using OpenSim.Framework.Statistics; using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; using OpenMetaverse; using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket; @@ -901,25 +900,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!m_scene.TryGetClient(agentID, out existingClient)) { - IHomeUsersSecurityService security = m_scene.RequestModuleInterface(); - if (security != null) - { - IPEndPoint ep = security.GetEndPoint(sessionID); - if (ep != null && ep.ToString() != remoteEndPoint.ToString()) - { - // uh-oh, this is fishy - m_log.WarnFormat("[LLUDPSERVER]: Agent {0} with session {1} connecting with unidentified end point. Refusing service.", agentID, sessionID); - m_log.WarnFormat("[LLUDPSERVER]: EP was {0}, now is {1}", ep.ToString(), remoteEndPoint.ToString()); - return; - } - else if (ep != null) - { - // ok, you're home, welcome back - m_log.InfoFormat("LLUDPSERVER]: Agent {0} is coming back to this grid", agentID); - security.RemoveEndPoint(sessionID); - } - } - // Create the LLClientView LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); client.OnLogout += LogoutHandler; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ed8c0fd..44f1191 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -237,9 +237,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) { + if (reg == null || finalDestination == null) + { + sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); + return; + } + m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}:{2}/{3} final destination {4}", - reg.ExternalHostName, reg.HttpPort, reg.RegionName, position, finalDestination.RegionName); + "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}:{2}/{3}", + reg.ExternalHostName, reg.HttpPort, finalDestination.RegionName, position); uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 4d5844c..85c2742 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -44,14 +44,13 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule + public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool m_Initialized = false; private GatekeeperServiceConnector m_GatekeeperConnector; - private IHomeUsersSecurityService m_Security; #region ISharedRegionModule @@ -69,21 +68,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (name == Name) { m_agentsInTransit = new List(); - - IConfig config = source.Configs["HGEntityTransferModule"]; - if (config != null) - { - string dll = config.GetString("HomeUsersSecurityService", string.Empty); - if (dll != string.Empty) - { - Object[] args = new Object[] { source }; - m_Security = ServerUtils.LoadPlugin(dll, args); - if (m_Security == null) - m_log.Debug("[HG ENTITY TRANSFER MODULE]: Unable to load Home Users Security service"); - else - m_log.Debug("[HG ENTITY TRANSFER MODULE]: Home Users Security service loaded"); - } - } m_Enabled = true; m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); @@ -95,7 +79,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { base.AddRegion(scene); if (m_Enabled) - scene.RegisterModuleInterface(m_Security); + { + scene.RegisterModuleInterface(this); + scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(OnNewClient); + } + } + + void OnNewClient(IClientAPI client) + { + client.OnLogout += new Action(OnLogout); } public override void RegionLoaded(Scene scene) @@ -113,13 +105,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { base.AddRegion(scene); if (m_Enabled) - scene.UnregisterModuleInterface(m_Security); + { + scene.UnregisterModuleInterface(this); + } } #endregion - #region HG overrides + #region HG overrides of IEntiryTransferModule protected override GridRegion GetFinalDestination(GridRegion region) { @@ -142,26 +136,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { reason = string.Empty; int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); - if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) + if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid - // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination - GridRegion region = new GridRegion(reg); - region.RegionName = finalDestination.RegionName; - region.RegionID = finalDestination.RegionID; - region.RegionLocX = finalDestination.RegionLocX; - region.RegionLocY = finalDestination.RegionLocY; - - // Log their session and remote endpoint in the home users security service - IHomeUsersSecurityService security = sp.Scene.RequestModuleInterface(); - if (security != null) - security.SetEndPoint(sp.ControllingClient.SessionId, sp.ControllingClient.RemoteEndPoint); - - //string token = sp.Scene.AuthenticationService.MakeToken(sp.UUID, reg.ExternalHostName + ":" + reg.HttpPort, 30); - // Log them out of this grid - sp.Scene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); - - return m_GatekeeperConnector.CreateAgent(region, agentCircuit, teleportFlags, out reason); + string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); + bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); + if (success) + // Log them out of this grid + m_aScene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); + + return success; } return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); @@ -184,23 +169,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Foreign user wants to go home // AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); - if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("GatewayURI"))) + if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("HomeURI"))) { client.SendTeleportFailed("Your information has been lost"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); return; } - GridRegion homeGatekeeper = MakeRegion(aCircuit); - if (homeGatekeeper == null) - { - client.SendTeleportFailed("Your information has been lost"); - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's gateway information is malformed"); - return; - } - + IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; - GridRegion finalDestination = m_GatekeeperConnector.GetHomeRegion(homeGatekeeper, aCircuit.AgentID, out position, out lookAt); + GridRegion finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt); if (finalDestination == null) { client.SendTeleportFailed("Your home region could not be found"); @@ -216,20 +194,52 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}", + IEventQueue eq = sp.Scene.RequestModuleInterface(); + GridRegion homeGatekeeper = MakeRegion(aCircuit); + + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}", aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ExternalHostName, homeGatekeeper.HttpPort, homeGatekeeper.RegionName); - IEventQueue eq = sp.Scene.RequestModuleInterface(); DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); } #endregion + #region IUserAgentVerificationModule + + public bool VerifyClient(AgentCircuitData aCircuit, string token) + { + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string url = aCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService security = new UserAgentServiceConnector(url); + return security.VerifyClient(aCircuit.SessionID, token); + } + + return false; + } + + void OnLogout(IClientAPI obj) + { + AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); + + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string url = aCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService security = new UserAgentServiceConnector(url); + security.LogoutAgent(obj.AgentId, obj.SessionId); + } + + } + + #endregion + private GridRegion MakeRegion(AgentCircuitData aCircuit) { GridRegion region = new GridRegion(); Uri uri = null; - if (!Uri.TryCreate(aCircuit.ServiceURLs["GatewayURI"].ToString(), UriKind.Absolute, out uri)) + if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") || + (aCircuit.ServiceURLs.ContainsKey("HomeURI") && !Uri.TryCreate(aCircuit.ServiceURLs["HomeURI"].ToString(), UriKind.Absolute, out uri))) return null; region.ExternalHostName = uri.Host; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index 6e6946c..c737f8b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs @@ -115,11 +115,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid m_log.Info("[HypergridService]: Starting..."); -// Object[] args = new Object[] { m_Config, MainServer.Instance }; ISimulationService simService = scene.RequestModuleInterface(); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); - //ServerUtils.LoadPlugin("OpenSim.Server.Handlers.dll:HypergridServiceInConnector", args); scene.RegisterModuleInterface(m_HypergridHandler.GateKeeper); + + new UserAgentServerConnector(m_Config, MainServer.Instance); } } diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 73c68f1..e8738c4 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -52,4 +52,9 @@ namespace OpenSim.Region.Framework.Interfaces void Cross(SceneObjectGroup sog, Vector3 position, bool silent); } + + public interface IUserAgentVerificationModule + { + bool VerifyClient(AgentCircuitData aCircuit, string token); + } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3cfb236..f800d5f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2416,6 +2416,37 @@ namespace OpenSim.Region.Framework.Scenes { AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); + // Do the verification here + System.Net.EndPoint ep = client.GetClientEP(); + if (aCircuit != null) + { + 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); + IUserAgentVerificationModule userVerification = RequestModuleInterface(); + if (userVerification != null) + { + 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); + } + } + } + m_log.Debug("[Scene] Adding new agent " + client.Name + " to scene " + RegionInfo.RegionName); /* string logMsg = string.Format("[SCENE]: Adding new {0} agent for {1} in {2}", @@ -2426,7 +2457,6 @@ namespace OpenSim.Region.Framework.Scenes */ //CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); - ScenePresence sp = CreateAndAddScenePresence(client); sp.Appearance = aCircuit.Appearance; @@ -3243,6 +3273,7 @@ namespace OpenSim.Region.Framework.Scenes } } + agent.teleportFlags = teleportFlags; m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); return true; diff --git a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs index 01e368c..c951653 100644 --- a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs @@ -49,12 +49,12 @@ using log4net; namespace OpenSim.Server.Handlers.Hypergrid { - public class AgentHandler : OpenSim.Server.Handlers.Simulation.AgentHandler + public class GatekeeperAgentHandler : OpenSim.Server.Handlers.Simulation.AgentHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IGatekeeperService m_GatekeeperService; - public AgentHandler(IGatekeeperService gatekeeper) + public GatekeeperAgentHandler(IGatekeeperService gatekeeper) { m_GatekeeperService = gatekeeper; } diff --git a/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs index c73b110..f2d9321 100644 --- a/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs @@ -68,9 +68,8 @@ namespace OpenSim.Server.Handlers.Hypergrid HypergridHandlers hghandlers = new HypergridHandlers(m_GatekeeperService); server.AddXmlRPCHandler("link_region", hghandlers.LinkRegionRequest, false); server.AddXmlRPCHandler("get_region", hghandlers.GetRegion, false); - server.AddXmlRPCHandler("get_home_region", hghandlers.GetHomeRegion, false); - server.AddHTTPHandler("/foreignagent/", new AgentHandler(m_GatekeeperService).Handler); + server.AddHTTPHandler("/foreignagent/", new GatekeeperAgentHandler(m_GatekeeperService).Handler); } diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeUsersSecurityServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HomeUsersSecurityServerConnector.cs deleted file mode 100644 index 5379784..0000000 --- a/OpenSim/Server/Handlers/Hypergrid/HomeUsersSecurityServerConnector.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Net; -using System.Reflection; - -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Server.Base; -using OpenSim.Services.Interfaces; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Server.Handlers.Base; - -using log4net; -using Nwc.XmlRpc; -using OpenMetaverse; - -namespace OpenSim.Server.Handlers.Hypergrid -{ - public class HomeUsersSecurityServerConnector : ServiceConnector - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private IHomeUsersSecurityService m_HomeUsersService; - - public HomeUsersSecurityServerConnector(IConfigSource config, IHttpServer server) : - base(config, server, String.Empty) - { - IConfig gridConfig = config.Configs["HomeUsersSecurityService"]; - if (gridConfig != null) - { - string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); - Object[] args = new Object[] { config }; - m_HomeUsersService = ServerUtils.LoadPlugin(serviceDll, args); - } - if (m_HomeUsersService == null) - throw new Exception("HomeUsersSecurity server connector cannot proceed because of missing service"); - - server.AddXmlRPCHandler("ep_get", GetEndPoint, false); - server.AddXmlRPCHandler("ep_set", SetEndPoint, false); - server.AddXmlRPCHandler("ep_remove", RemoveEndPoint, false); - - } - - public XmlRpcResponse GetEndPoint(XmlRpcRequest request, IPEndPoint remoteClient) - { - Hashtable requestData = (Hashtable)request.Params[0]; - //string host = (string)requestData["host"]; - //string portstr = (string)requestData["port"]; - string sessionID_str = (string)requestData["sessionID"]; - UUID sessionID = UUID.Zero; - UUID.TryParse(sessionID_str, out sessionID); - - IPEndPoint ep = m_HomeUsersService.GetEndPoint(sessionID); - - Hashtable hash = new Hashtable(); - if (ep == null) - hash["result"] = "false"; - else - { - hash["result"] = "true"; - hash["ep_addr"] = ep.Address.ToString(); - hash["ep_port"] = ep.Port.ToString(); - } - XmlRpcResponse response = new XmlRpcResponse(); - response.Value = hash; - return response; - - } - - public XmlRpcResponse SetEndPoint(XmlRpcRequest request, IPEndPoint remoteClient) - { - Hashtable requestData = (Hashtable)request.Params[0]; - string host = (string)requestData["ep_addr"]; - string portstr = (string)requestData["ep_port"]; - string sessionID_str = (string)requestData["sessionID"]; - UUID sessionID = UUID.Zero; - UUID.TryParse(sessionID_str, out sessionID); - int port = 0; - Int32.TryParse(portstr, out port); - - IPEndPoint ep = null; - try - { - ep = new IPEndPoint(IPAddress.Parse(host), port); - } - catch - { - m_log.Debug("[HOME USERS SECURITY]: Exception in creating EndPoint"); - } - - m_HomeUsersService.SetEndPoint(sessionID, ep); - - Hashtable hash = new Hashtable(); - hash["result"] = "true"; - XmlRpcResponse response = new XmlRpcResponse(); - response.Value = hash; - return response; - - } - - public XmlRpcResponse RemoveEndPoint(XmlRpcRequest request, IPEndPoint remoteClient) - { - Hashtable requestData = (Hashtable)request.Params[0]; - string sessionID_str = (string)requestData["sessionID"]; - UUID sessionID = UUID.Zero; - UUID.TryParse(sessionID_str, out sessionID); - - m_HomeUsersService.RemoveEndPoint(sessionID); - - Hashtable hash = new Hashtable(); - hash["result"] = "true"; - XmlRpcResponse response = new XmlRpcResponse(); - response.Value = hash; - return response; - - } - - } -} diff --git a/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs index 7d31730..0b65245 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs @@ -113,38 +113,5 @@ namespace OpenSim.Server.Handlers.Hypergrid } - public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient) - { - Hashtable requestData = (Hashtable)request.Params[0]; - //string host = (string)requestData["host"]; - //string portstr = (string)requestData["port"]; - string userID_str = (string)requestData["userID"]; - UUID userID = UUID.Zero; - UUID.TryParse(userID_str, out userID); - - Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; - GridRegion regInfo = m_GatekeeperService.GetHomeRegion(userID, out position, out lookAt); - - Hashtable hash = new Hashtable(); - if (regInfo == null) - hash["result"] = "false"; - else - { - hash["result"] = "true"; - hash["uuid"] = regInfo.RegionID.ToString(); - hash["x"] = regInfo.RegionLocX.ToString(); - hash["y"] = regInfo.RegionLocY.ToString(); - hash["region_name"] = regInfo.RegionName; - hash["hostname"] = regInfo.ExternalHostName; - hash["http_port"] = regInfo.HttpPort.ToString(); - hash["internal_port"] = regInfo.InternalEndPoint.Port.ToString(); - hash["position"] = position.ToString(); - hash["lookAt"] = lookAt.ToString(); - } - XmlRpcResponse response = new XmlRpcResponse(); - response.Value = hash; - return response; - - } } } diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs new file mode 100644 index 0000000..79c6b2a --- /dev/null +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; +using System.Reflection; + +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using log4net; +using Nwc.XmlRpc; +using OpenMetaverse; + +namespace OpenSim.Server.Handlers.Hypergrid +{ + public class UserAgentServerConnector : ServiceConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private IUserAgentService m_HomeUsersService; + + public UserAgentServerConnector(IConfigSource config, IHttpServer server) : + base(config, server, String.Empty) + { + IConfig gridConfig = config.Configs["UserAgentService"]; + if (gridConfig != null) + { + string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); + Object[] args = new Object[] { config }; + m_HomeUsersService = ServerUtils.LoadPlugin(serviceDll, args); + } + if (m_HomeUsersService == null) + throw new Exception("UserAgent server connector cannot proceed because of missing service"); + + server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false); + server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false); + server.AddXmlRPCHandler("verify_agent", VerifyAgent, false); + server.AddXmlRPCHandler("verify_client", VerifyClient, false); + server.AddXmlRPCHandler("logout_agent", LogoutAgent, false); + + server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService).Handler); + } + + public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + + Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; + GridRegion regInfo = m_HomeUsersService.GetHomeRegion(userID, out position, out lookAt); + + Hashtable hash = new Hashtable(); + if (regInfo == null) + hash["result"] = "false"; + else + { + hash["result"] = "true"; + hash["uuid"] = regInfo.RegionID.ToString(); + hash["x"] = regInfo.RegionLocX.ToString(); + hash["y"] = regInfo.RegionLocY.ToString(); + hash["region_name"] = regInfo.RegionName; + hash["hostname"] = regInfo.ExternalHostName; + hash["http_port"] = regInfo.HttpPort.ToString(); + hash["internal_port"] = regInfo.InternalEndPoint.Port.ToString(); + hash["position"] = position.ToString(); + hash["lookAt"] = lookAt.ToString(); + } + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + public XmlRpcResponse AgentIsComingHome(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + string sessionID_str = (string)requestData["sessionID"]; + UUID sessionID = UUID.Zero; + UUID.TryParse(sessionID_str, out sessionID); + string gridName = (string)requestData["externalName"]; + + bool success = m_HomeUsersService.AgentIsComingHome(sessionID, gridName); + + Hashtable hash = new Hashtable(); + hash["result"] = success.ToString(); + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + public XmlRpcResponse VerifyAgent(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + string sessionID_str = (string)requestData["sessionID"]; + UUID sessionID = UUID.Zero; + UUID.TryParse(sessionID_str, out sessionID); + string token = (string)requestData["token"]; + + bool success = m_HomeUsersService.VerifyAgent(sessionID, token); + + Hashtable hash = new Hashtable(); + hash["result"] = success.ToString(); + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + public XmlRpcResponse VerifyClient(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + string sessionID_str = (string)requestData["sessionID"]; + UUID sessionID = UUID.Zero; + UUID.TryParse(sessionID_str, out sessionID); + string token = (string)requestData["token"]; + + bool success = m_HomeUsersService.VerifyClient(sessionID, token); + + Hashtable hash = new Hashtable(); + hash["result"] = success.ToString(); + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + public XmlRpcResponse LogoutAgent(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + string sessionID_str = (string)requestData["sessionID"]; + UUID sessionID = UUID.Zero; + UUID.TryParse(sessionID_str, out sessionID); + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + + m_HomeUsersService.LogoutAgent(userID, sessionID); + + Hashtable hash = new Hashtable(); + hash["result"] = "true"; + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + } +} diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 5ad1af2..608228d 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -241,95 +241,5 @@ namespace OpenSim.Services.Connectors.Hypergrid return null; } - public GridRegion GetHomeRegion(GridRegion gatekeeper, UUID userID, out Vector3 position, out Vector3 lookAt) - { - position = Vector3.UnitY; lookAt = Vector3.UnitY; - - Hashtable hash = new Hashtable(); - hash["userID"] = userID.ToString(); - - IList paramList = new ArrayList(); - paramList.Add(hash); - - XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList); - string uri = "http://" + gatekeeper.ExternalHostName + ":" + gatekeeper.HttpPort + "/"; - XmlRpcResponse response = null; - try - { - response = request.Send(uri, 10000); - } - catch (Exception e) - { - return null; - } - - if (response.IsFault) - { - return null; - } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try - { - bool success = false; - Boolean.TryParse((string)hash["result"], out success); - if (success) - { - GridRegion region = new GridRegion(); - - UUID.TryParse((string)hash["uuid"], out region.RegionID); - //m_log.Debug(">> HERE, uuid: " + region.RegionID); - int n = 0; - if (hash["x"] != null) - { - Int32.TryParse((string)hash["x"], out n); - region.RegionLocX = n; - //m_log.Debug(">> HERE, x: " + region.RegionLocX); - } - if (hash["y"] != null) - { - Int32.TryParse((string)hash["y"], out n); - region.RegionLocY = n; - //m_log.Debug(">> HERE, y: " + region.RegionLocY); - } - if (hash["region_name"] != null) - { - region.RegionName = (string)hash["region_name"]; - //m_log.Debug(">> HERE, name: " + region.RegionName); - } - if (hash["hostname"] != null) - region.ExternalHostName = (string)hash["hostname"]; - if (hash["http_port"] != null) - { - uint p = 0; - UInt32.TryParse((string)hash["http_port"], out p); - region.HttpPort = p; - } - if (hash["internal_port"] != null) - { - int p = 0; - Int32.TryParse((string)hash["internal_port"], out p); - region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); - } - if (hash["position"] != null) - Vector3.TryParse((string)hash["position"], out position); - if (hash["lookAt"] != null) - Vector3.TryParse((string)hash["lookAt"], out lookAt); - - // Successful return - return region; - } - - } - catch (Exception e) - { - return null; - } - - return null; - - } } } diff --git a/OpenSim/Services/Connectors/Hypergrid/HomeUsersSecurityServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HomeUsersSecurityServiceConnector.cs deleted file mode 100644 index 150690b..0000000 --- a/OpenSim/Services/Connectors/Hypergrid/HomeUsersSecurityServiceConnector.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Net; -using System.Reflection; - -using OpenSim.Services.Interfaces; - -using OpenMetaverse; -using log4net; -using Nwc.XmlRpc; -using Nini.Config; - -namespace OpenSim.Services.Connectors.Hypergrid -{ - public class HomeUsersSecurityServiceConnector : IHomeUsersSecurityService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - string m_ServerURL; - public HomeUsersSecurityServiceConnector(string url) - { - m_ServerURL = url; - } - - public HomeUsersSecurityServiceConnector(IConfigSource config) - { - } - - public void SetEndPoint(UUID sessionID, IPEndPoint ep) - { - Hashtable hash = new Hashtable(); - hash["sessionID"] = sessionID.ToString(); - hash["ep_addr"] = ep.Address.ToString(); - hash["ep_port"] = ep.Port.ToString(); - - Call("ep_set", hash); - } - - public void RemoveEndPoint(UUID sessionID) - { - Hashtable hash = new Hashtable(); - hash["sessionID"] = sessionID.ToString(); - - Call("ep_remove", hash); - } - - public IPEndPoint GetEndPoint(UUID sessionID) - { - Hashtable hash = new Hashtable(); - hash["sessionID"] = sessionID.ToString(); - - IList paramList = new ArrayList(); - paramList.Add(hash); - - XmlRpcRequest request = new XmlRpcRequest("ep_get", paramList); - //m_log.Debug("[HGrid]: Linking to " + uri); - XmlRpcResponse response = null; - try - { - response = request.Send(m_ServerURL, 10000); - } - catch (Exception e) - { - m_log.Debug("[HGrid]: Exception " + e.Message); - return null; - } - - if (response.IsFault) - { - m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); - return null; - } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try - { - bool success = false; - Boolean.TryParse((string)hash["result"], out success); - if (success) - { - IPEndPoint ep = null; - int port = 0; - if (hash["ep_port"] != null) - Int32.TryParse((string)hash["ep_port"], out port); - if (hash["ep_addr"] != null) - ep = new IPEndPoint(IPAddress.Parse((string)hash["ep_addr"]), port); - - return ep; - } - - } - catch (Exception e) - { - m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace); - return null; - } - - return null; - } - - private void Call(string method, Hashtable hash) - { - IList paramList = new ArrayList(); - paramList.Add(hash); - - XmlRpcRequest request = new XmlRpcRequest(method, paramList); - XmlRpcResponse response = null; - try - { - response = request.Send(m_ServerURL, 10000); - } - catch (Exception e) - { - m_log.Debug("[HGrid]: Exception " + e.Message); - return ; - } - - if (response.IsFault) - { - m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); - return ; - } - - } - - } -} diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs new file mode 100644 index 0000000..83d3449 --- /dev/null +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -0,0 +1,370 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Simulation; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using log4net; +using Nwc.XmlRpc; +using Nini.Config; + +namespace OpenSim.Services.Connectors.Hypergrid +{ + public class UserAgentServiceConnector : IUserAgentService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + string m_ServerURL; + public UserAgentServiceConnector(string url) + { + m_ServerURL = url; + } + + public UserAgentServiceConnector(IConfigSource config) + { + } + + public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason) + { + reason = String.Empty; + + if (destination == null) + { + reason = "Destination is null"; + m_log.Debug("[USER AGENT CONNECTOR]: Given destination is null"); + return false; + } + + string uri = m_ServerURL + "/homeagent/" + aCircuit.AgentID + "/"; + + Console.WriteLine(" >>> LoginAgentToGrid <<< " + uri); + + HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri); + AgentCreateRequest.Method = "POST"; + AgentCreateRequest.ContentType = "application/json"; + AgentCreateRequest.Timeout = 10000; + //AgentCreateRequest.KeepAlive = false; + //AgentCreateRequest.Headers.Add("Authorization", authKey); + + // Fill it in + OSDMap args = PackCreateAgentArguments(aCircuit, gatekeeper, destination); + + string strBuffer = ""; + byte[] buffer = new byte[1]; + try + { + strBuffer = OSDParser.SerializeJsonString(args); + Encoding str = Util.UTF8; + buffer = str.GetBytes(strBuffer); + + } + catch (Exception e) + { + m_log.WarnFormat("[USER AGENT CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message); + // ignore. buffer will be empty, caller should check. + } + + Stream os = null; + try + { // send the Post + AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send + os = AgentCreateRequest.GetRequestStream(); + os.Write(buffer, 0, strBuffer.Length); //Send it + m_log.InfoFormat("[USER AGENT CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}", + uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY); + } + //catch (WebException ex) + catch + { + //m_log.InfoFormat("[USER AGENT CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message); + reason = "cannot contact remote region"; + return false; + } + finally + { + if (os != null) + os.Close(); + } + + // Let's wait for the response + //m_log.Info("[USER AGENT CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall"); + + WebResponse webResponse = null; + StreamReader sr = null; + try + { + webResponse = AgentCreateRequest.GetResponse(); + if (webResponse == null) + { + m_log.Info("[USER AGENT CONNECTOR]: Null reply on DoCreateChildAgentCall post"); + } + else + { + + sr = new StreamReader(webResponse.GetResponseStream()); + string response = sr.ReadToEnd().Trim(); + m_log.InfoFormat("[USER AGENT CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response); + + if (!String.IsNullOrEmpty(response)) + { + try + { + // we assume we got an OSDMap back + OSDMap r = Util.GetOSDMap(response); + bool success = r["success"].AsBoolean(); + reason = r["reason"].AsString(); + return success; + } + catch (NullReferenceException e) + { + m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message); + + // check for old style response + if (response.ToLower().StartsWith("true")) + return true; + + return false; + } + } + } + } + catch (WebException ex) + { + m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message); + reason = "Destination did not reply"; + return false; + } + finally + { + if (sr != null) + sr.Close(); + } + + return true; + + } + + protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination) + { + OSDMap args = null; + try + { + args = aCircuit.PackAgentCircuitData(); + } + catch (Exception e) + { + m_log.Debug("[USER AGENT CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message); + } + // Add the input arguments + args["gatekeeper_host"] = OSD.FromString(gatekeeper.ExternalHostName); + args["gatekeeper_port"] = OSD.FromString(gatekeeper.HttpPort.ToString()); + args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString()); + args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString()); + args["destination_name"] = OSD.FromString(destination.RegionName); + args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); + + return args; + } + + public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt) + { + position = Vector3.UnitY; lookAt = Vector3.UnitY; + + Hashtable hash = new Hashtable(); + hash["userID"] = userID.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList); + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + return null; + } + + if (response.IsFault) + { + return null; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + bool success = false; + Boolean.TryParse((string)hash["result"], out success); + if (success) + { + GridRegion region = new GridRegion(); + + UUID.TryParse((string)hash["uuid"], out region.RegionID); + //m_log.Debug(">> HERE, uuid: " + region.RegionID); + int n = 0; + if (hash["x"] != null) + { + Int32.TryParse((string)hash["x"], out n); + region.RegionLocX = n; + //m_log.Debug(">> HERE, x: " + region.RegionLocX); + } + if (hash["y"] != null) + { + Int32.TryParse((string)hash["y"], out n); + region.RegionLocY = n; + //m_log.Debug(">> HERE, y: " + region.RegionLocY); + } + if (hash["region_name"] != null) + { + region.RegionName = (string)hash["region_name"]; + //m_log.Debug(">> HERE, name: " + region.RegionName); + } + if (hash["hostname"] != null) + region.ExternalHostName = (string)hash["hostname"]; + if (hash["http_port"] != null) + { + uint p = 0; + UInt32.TryParse((string)hash["http_port"], out p); + region.HttpPort = p; + } + if (hash["internal_port"] != null) + { + int p = 0; + Int32.TryParse((string)hash["internal_port"], out p); + region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); + } + if (hash["position"] != null) + Vector3.TryParse((string)hash["position"], out position); + if (hash["lookAt"] != null) + Vector3.TryParse((string)hash["lookAt"], out lookAt); + + // Successful return + return region; + } + + } + catch (Exception e) + { + return null; + } + + return null; + + } + + public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName) + { + Hashtable hash = new Hashtable(); + hash["sessionID"] = sessionID.ToString(); + hash["externalName"] = thisGridExternalName; + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("agent_is_coming_home", paramList); + string reason = string.Empty; + return GetBoolResponse(request, out reason); + } + + public bool VerifyAgent(UUID sessionID, string token) + { + Hashtable hash = new Hashtable(); + hash["sessionID"] = sessionID.ToString(); + hash["token"] = token; + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("verify_agent", paramList); + string reason = string.Empty; + return GetBoolResponse(request, out reason); + } + + public bool VerifyClient(UUID sessionID, string token) + { + Hashtable hash = new Hashtable(); + hash["sessionID"] = sessionID.ToString(); + hash["token"] = token; + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("verify_client", paramList); + string reason = string.Empty; + return GetBoolResponse(request, out reason); + } + + public void LogoutAgent(UUID userID, UUID sessionID) + { + Hashtable hash = new Hashtable(); + hash["sessionID"] = sessionID.ToString(); + hash["userID"] = userID.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("logout_agent", paramList); + string reason = string.Empty; + GetBoolResponse(request, out reason); + } + + + private bool GetBoolResponse(XmlRpcRequest request, out string reason) + { + //m_log.Debug("[HGrid]: Linking to " + uri); + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.Debug("[HGrid]: Exception " + e.Message); + reason = "Exception: " + e.Message; + return false; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); + reason = "XMLRPC Fault"; + return false; + } + + Hashtable hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + bool success = false; + reason = string.Empty; + Boolean.TryParse((string)hash["result"], out success); + + return success; + } + catch (Exception e) + { + m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace); + reason = "Exception: " + e.Message; + return false; + } + + } + + } +} diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 683fe79..e2ab179 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -104,21 +104,7 @@ namespace OpenSim.Services.Connectors.Simulation //AgentCreateRequest.Headers.Add("Authorization", authKey); // Fill it in - OSDMap args = null; - try - { - args = aCircuit.PackAgentCircuitData(); - } - catch (Exception e) - { - m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message); - } - // Add the input arguments - args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString()); - args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString()); - args["destination_name"] = OSD.FromString(destination.RegionName); - args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); - args["teleport_flags"] = OSD.FromString(flags.ToString()); + OSDMap args = PackCreateAgentArguments(aCircuit, destination, flags); string strBuffer = ""; byte[] buffer = new byte[1]; @@ -214,6 +200,27 @@ namespace OpenSim.Services.Connectors.Simulation return true; } + protected virtual OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion destination, uint flags) + { + OSDMap args = null; + try + { + args = aCircuit.PackAgentCircuitData(); + } + catch (Exception e) + { + m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message); + } + // Add the input arguments + args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString()); + args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString()); + args["destination_name"] = OSD.FromString(destination.RegionName); + args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); + args["teleport_flags"] = OSD.FromString(flags.ToString()); + + return args; + } + public bool UpdateAgent(GridRegion destination, AgentData data) { return UpdateAgent(destination, (IAgentData)data); diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 3cb5d50..3bf0836 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -34,6 +34,7 @@ using OpenSim.Framework; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using OpenSim.Server.Base; +using OpenSim.Services.Connectors.Hypergrid; using OpenMetaverse; @@ -50,9 +51,8 @@ namespace OpenSim.Services.HypergridService IGridService m_GridService; IPresenceService m_PresenceService; - IAuthenticationService m_AuthenticationService; IUserAccountService m_UserAccountService; - IHomeUsersSecurityService m_HomeUsersSecurityService; + IUserAgentService m_UserAgentService; ISimulationService m_SimulationService; string m_AuthDll; @@ -69,12 +69,12 @@ namespace OpenSim.Services.HypergridService throw new Exception(String.Format("No section GatekeeperService in config file")); string accountService = serverConfig.GetString("UserAccountService", String.Empty); - string homeUsersSecurityService = serverConfig.GetString("HomeUsersSecurityService", string.Empty); + string homeUsersService = serverConfig.GetString("HomeUsersSecurityService", string.Empty); string gridService = serverConfig.GetString("GridService", String.Empty); string presenceService = serverConfig.GetString("PresenceService", String.Empty); string simulationService = serverConfig.GetString("SimulationService", String.Empty); - m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty); + //m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty); // These 3 are mandatory, the others aren't if (gridService == string.Empty || presenceService == string.Empty || m_AuthDll == string.Empty) @@ -92,8 +92,8 @@ namespace OpenSim.Services.HypergridService if (accountService != string.Empty) m_UserAccountService = ServerUtils.LoadPlugin(accountService, args); - if (homeUsersSecurityService != string.Empty) - m_HomeUsersSecurityService = ServerUtils.LoadPlugin(homeUsersSecurityService, args); + if (homeUsersService != string.Empty) + m_UserAgentService = ServerUtils.LoadPlugin(homeUsersService, args); if (simService != null) m_SimulationService = simService; @@ -206,13 +206,12 @@ namespace OpenSim.Services.HypergridService account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID); if (account != null) { - // Make sure this is the user coming home, and not a fake - if (m_HomeUsersSecurityService != null) + // Make sure this is the user coming home, and not a foreign user with same UUID as a local user + if (m_UserAgentService != null) { - Object ep = m_HomeUsersSecurityService.GetEndPoint(aCircuit.SessionID); - if (ep == null) + if (!m_UserAgentService.AgentIsComingHome(aCircuit.SessionID, m_ExternalName)) { - // This is a fake, this session never left this grid + // Can't do, sorry reason = "Unauthorized"; m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.", aCircuit.firstname, aCircuit.lastname); @@ -266,32 +265,35 @@ namespace OpenSim.Services.HypergridService // // Finally launch the agent at the destination // - return m_SimulationService.CreateAgent(destination, aCircuit, 0, out reason); + return m_SimulationService.CreateAgent(destination, aCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); } protected bool Authenticate(AgentCircuitData aCircuit) { - string authURL = string.Empty; + if (!CheckAddress(aCircuit.ServiceSessionID)) + return false; + + string userURL = string.Empty; if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) - authURL = aCircuit.ServiceURLs["HomeURI"].ToString(); + userURL = aCircuit.ServiceURLs["HomeURI"].ToString(); - if (authURL == string.Empty) + if (userURL == string.Empty) { m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL"); return false; } - Object[] args = new Object[] { authURL }; - IAuthenticationService authService = ServerUtils.LoadPlugin(m_AuthDll, args); - if (authService != null) + Object[] args = new Object[] { userURL }; + IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); //ServerUtils.LoadPlugin(m_AuthDll, args); + if (userAgentService != null) { try { - return authService.Verify(aCircuit.AgentID, aCircuit.SecureSessionID.ToString(), 30); + return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); } catch { - m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", authURL); + m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL); return false; } } @@ -299,35 +301,20 @@ namespace OpenSim.Services.HypergridService return false; } - #endregion - - public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt) + // Check that the service token was generated for *this* grid. + // If it wasn't then that's a fake agent. + protected bool CheckAddress(string serviceToken) { - position = new Vector3(128, 128, 0); lookAt = Vector3.UnitY; + string[] parts = serviceToken.Split(new char[] { ';' }); + if (parts.Length < 2) + return false; - m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to get home region of user {0}", userID); + string addressee = parts[0]; + return (addressee == m_ExternalName); + } - GridRegion home = null; - PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { userID.ToString() }); - if (presences != null && presences.Length > 0) - { - UUID homeID = presences[0].HomeRegionID; - if (homeID != UUID.Zero) - { - home = m_GridService.GetRegionByUUID(m_ScopeID, homeID); - position = presences[0].HomePosition; - lookAt = presences[0].HomeLookAt; - } - if (home == null) - { - List defs = m_GridService.GetDefaultRegions(m_ScopeID); - if (defs != null && defs.Count > 0) - home = defs[0]; - } - } + #endregion - return home; - } #region Misc diff --git a/OpenSim/Services/HypergridService/HomeUsersSecurityService.cs b/OpenSim/Services/HypergridService/HomeUsersSecurityService.cs deleted file mode 100644 index a7adfc1..0000000 --- a/OpenSim/Services/HypergridService/HomeUsersSecurityService.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Reflection; - -using OpenSim.Services.Interfaces; - -using OpenMetaverse; -using log4net; -using Nini.Config; - -namespace OpenSim.Services.HypergridService -{ - /// - /// This service is for HG1.5 only, to make up for the fact that clients don't - /// keep any private information in themselves, and that their 'home service' - /// needs to do it for them. - /// Once we have better clients, this shouldn't be needed. - /// - public class HomeUsersSecurityService : IHomeUsersSecurityService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - // - // This is a persistent storage wannabe for dealing with the - // quirks of HG1.5. We don't really want to store this in a table. - // But this is the necessary information for securing clients - // coming home. - // - protected static Dictionary m_ClientEndPoints = new Dictionary(); - - public HomeUsersSecurityService(IConfigSource config) - { - m_log.DebugFormat("[HOME USERS SECURITY]: Starting..."); - } - - public void SetEndPoint(UUID sessionID, IPEndPoint ep) - { - m_log.DebugFormat("[HOME USERS SECURITY]: Set EndPoint {0} for session {1}", ep.ToString(), sessionID); - - lock (m_ClientEndPoints) - m_ClientEndPoints[sessionID] = ep; - } - - public IPEndPoint GetEndPoint(UUID sessionID) - { - lock (m_ClientEndPoints) - if (m_ClientEndPoints.ContainsKey(sessionID)) - { - m_log.DebugFormat("[HOME USERS SECURITY]: Get EndPoint {0} for session {1}", m_ClientEndPoints[sessionID].ToString(), sessionID); - return m_ClientEndPoints[sessionID]; - } - - return null; - } - - public void RemoveEndPoint(UUID sessionID) - { - m_log.DebugFormat("[HOME USERS SECURITY]: Remove EndPoint for session {0}", sessionID); - lock (m_ClientEndPoints) - if (m_ClientEndPoints.ContainsKey(sessionID)) - m_ClientEndPoints.Remove(sessionID); - } - } -} diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs new file mode 100644 index 0000000..0873a2b --- /dev/null +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; + +using OpenSim.Framework; +using OpenSim.Services.Connectors.Hypergrid; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; + +using OpenMetaverse; +using log4net; +using Nini.Config; + +namespace OpenSim.Services.HypergridService +{ + /// + /// This service is for HG1.5 only, to make up for the fact that clients don't + /// keep any private information in themselves, and that their 'home service' + /// needs to do it for them. + /// Once we have better clients, this shouldn't be needed. + /// + public class UserAgentService : IUserAgentService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + // This will need to go into a DB table + static Dictionary m_TravelingAgents = new Dictionary(); + + static bool m_Initialized = false; + + protected static IPresenceService m_PresenceService; + protected static IGridService m_GridService; + protected static GatekeeperServiceConnector m_GatekeeperConnector; + + public UserAgentService(IConfigSource config) + { + if (!m_Initialized) + { + m_log.DebugFormat("[HOME USERS SECURITY]: Starting..."); + + IConfig serverConfig = config.Configs["UserAgentService"]; + if (serverConfig == null) + throw new Exception(String.Format("No section UserAgentService in config file")); + + string gridService = serverConfig.GetString("GridService", String.Empty); + string presenceService = serverConfig.GetString("PresenceService", String.Empty); + + if (gridService == string.Empty || presenceService == string.Empty) + throw new Exception(String.Format("Incomplete specifications, UserAgent Service cannot function.")); + + Object[] args = new Object[] { config }; + m_GridService = ServerUtils.LoadPlugin(gridService, args); + m_PresenceService = ServerUtils.LoadPlugin(presenceService, args); + m_GatekeeperConnector = new GatekeeperServiceConnector(); + + m_Initialized = true; + } + } + + public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt) + { + position = new Vector3(128, 128, 0); lookAt = Vector3.UnitY; + + m_log.DebugFormat("[USER AGENT SERVICE]: Request to get home region of user {0}", userID); + + GridRegion home = null; + PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { userID.ToString() }); + if (presences != null && presences.Length > 0) + { + UUID homeID = presences[0].HomeRegionID; + if (homeID != UUID.Zero) + { + home = m_GridService.GetRegionByUUID(UUID.Zero, homeID); + position = presences[0].HomePosition; + lookAt = presences[0].HomeLookAt; + } + if (home == null) + { + List defs = m_GridService.GetDefaultRegions(UUID.Zero); + if (defs != null && defs.Count > 0) + home = defs[0]; + } + } + + return home; + } + + public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason) + { + m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} to grid {2}", + agentCircuit.firstname, agentCircuit.lastname, gatekeeper.ExternalHostName +":"+ gatekeeper.HttpPort); + + // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination + GridRegion region = new GridRegion(gatekeeper); + region.RegionName = finalDestination.RegionName; + region.RegionID = finalDestination.RegionID; + region.RegionLocX = finalDestination.RegionLocX; + region.RegionLocY = finalDestination.RegionLocY; + + // Generate a new service session + agentCircuit.ServiceSessionID = "http://" + region.ExternalHostName + ":" + region.HttpPort + ";" + UUID.Random(); + TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); + + bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); + + if (!success) + { + m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}", + agentCircuit.firstname, agentCircuit.lastname, region.ExternalHostName + ":" + region.HttpPort, reason); + + // restore the old travel info + lock (m_TravelingAgents) + m_TravelingAgents[agentCircuit.SessionID] = old; + + return false; + } + + return true; + } + + TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region) + { + TravelingAgentInfo travel = new TravelingAgentInfo(); + TravelingAgentInfo old = null; + lock (m_TravelingAgents) + { + if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID)) + { + old = m_TravelingAgents[agentCircuit.SessionID]; + } + + m_TravelingAgents[agentCircuit.SessionID] = travel; + } + travel.UserID = agentCircuit.AgentID; + travel.GridExternalName = region.ExternalHostName + ":" + region.HttpPort; + travel.ServiceToken = agentCircuit.ServiceSessionID; + if (old != null) + travel.ClientToken = old.ClientToken; + + return old; + } + + public void LogoutAgent(UUID userID, UUID sessionID) + { + m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID); + + lock (m_TravelingAgents) + { + List travels = new List(); + foreach (KeyValuePair kvp in m_TravelingAgents) + if (kvp.Value.UserID == userID) + travels.Add(kvp.Key); + foreach (UUID session in travels) + m_TravelingAgents.Remove(session); + } + } + + // We need to prevent foreign users with the same UUID as a local user + public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName) + { + if (!m_TravelingAgents.ContainsKey(sessionID)) + return false; + + TravelingAgentInfo travel = m_TravelingAgents[sessionID]; + return travel.GridExternalName == thisGridExternalName; + } + + public bool VerifyClient(UUID sessionID, string token) + { + 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; + } + + public bool VerifyAgent(UUID sessionID, string token) + { + if (m_TravelingAgents.ContainsKey(sessionID)) + { + m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken); + return m_TravelingAgents[sessionID].ServiceToken == token; + } + + m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); + + return false; + } + + } + + class TravelingAgentInfo + { + public UUID UserID; + public string GridExternalName = string.Empty; + public string ServiceToken = string.Empty; + public string ClientToken = string.Empty; + } + +} diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs index f8eb817..ca7b9b3 100644 --- a/OpenSim/Services/Interfaces/IGatekeeperService.cs +++ b/OpenSim/Services/Interfaces/IGatekeeperService.cs @@ -41,17 +41,19 @@ namespace OpenSim.Services.Interfaces bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason); - GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); - } /// /// HG1.5 only /// - public interface IHomeUsersSecurityService + public interface IUserAgentService { - void SetEndPoint(UUID sessionID, IPEndPoint ep); - IPEndPoint GetEndPoint(UUID sessionID); - void RemoveEndPoint(UUID sessionID); + bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); + void LogoutAgent(UUID userID, UUID sessionID); + GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); + + bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); + bool VerifyAgent(UUID sessionID, string token); + bool VerifyClient(UUID sessionID, string token); } } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index d4f89d9..cacedf8 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -14,6 +14,7 @@ using OpenSim.Framework.Console; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Services.Connectors.Hypergrid; namespace OpenSim.Services.LLLoginService { @@ -31,11 +32,15 @@ namespace OpenSim.Services.LLLoginService private ISimulationService m_RemoteSimulationService; private ILibraryService m_LibraryService; private IAvatarService m_AvatarService; + private IUserAgentService m_UserAgentService; + + private GatekeeperServiceConnector m_GatekeeperConnector; private string m_DefaultRegionName; private string m_WelcomeMessage; private bool m_RequireInventory; private int m_MinLoginLevel; + private string m_GatekeeperURL; IConfig m_LoginServerConfig; @@ -46,6 +51,7 @@ namespace OpenSim.Services.LLLoginService throw new Exception(String.Format("No section LoginService in config file")); string accountService = m_LoginServerConfig.GetString("UserAccountService", String.Empty); + string agentService = m_LoginServerConfig.GetString("UserAgentService", String.Empty); string authService = m_LoginServerConfig.GetString("AuthenticationService", String.Empty); string invService = m_LoginServerConfig.GetString("InventoryService", String.Empty); string gridService = m_LoginServerConfig.GetString("GridService", String.Empty); @@ -57,6 +63,7 @@ namespace OpenSim.Services.LLLoginService m_DefaultRegionName = m_LoginServerConfig.GetString("DefaultRegion", String.Empty); m_WelcomeMessage = m_LoginServerConfig.GetString("WelcomeMessage", "Welcome to OpenSim!"); m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true); + m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); // These are required; the others aren't if (accountService == string.Empty || authService == string.Empty) @@ -74,6 +81,9 @@ namespace OpenSim.Services.LLLoginService m_AvatarService = ServerUtils.LoadPlugin(avatarService, args); if (simulationService != string.Empty) m_RemoteSimulationService = ServerUtils.LoadPlugin(simulationService, args); + if (agentService != string.Empty) + m_UserAgentService = ServerUtils.LoadPlugin(agentService, args); + // // deal with the services given as argument // @@ -89,6 +99,8 @@ namespace OpenSim.Services.LLLoginService m_LibraryService = ServerUtils.LoadPlugin(libService, args); } + m_GatekeeperConnector = new GatekeeperServiceConnector(); + if (!Initialized) { Initialized = true; @@ -185,7 +197,8 @@ namespace OpenSim.Services.LLLoginService string where = string.Empty; Vector3 position = Vector3.Zero; Vector3 lookAt = Vector3.Zero; - GridRegion destination = FindDestination(account, presence, session, startLocation, out where, out position, out lookAt); + GridRegion gatekeeper = null; + GridRegion destination = FindDestination(account, presence, session, startLocation, out gatekeeper, out where, out position, out lookAt); if (destination == null) { m_PresenceService.LogoutAgent(session, presence.Position, presence.LookAt); @@ -205,50 +218,16 @@ namespace OpenSim.Services.LLLoginService // // Instantiate/get the simulation interface and launch an agent at the destination // - ISimulationService simConnector = null; string reason = string.Empty; - uint circuitCode = 0; - AgentCircuitData aCircuit = null; - Object[] args = new Object[] { destination }; - // HG standalones have both a localSimulatonDll and a remoteSimulationDll - // non-HG standalones have just a localSimulationDll - // independent login servers have just a remoteSimulationDll - if (!startLocation.Contains("@") && (m_LocalSimulationService != null)) - simConnector = m_LocalSimulationService; - else if (m_RemoteSimulationService != null) - simConnector = m_RemoteSimulationService; - if (simConnector != null) - { - circuitCode = (uint)Util.RandomClass.Next(); ; - aCircuit = LaunchAgent(simConnector, destination, account, avatar, session, secureSession, circuitCode, position, out reason); - } + AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, out where, out reason); + if (aCircuit == null) { - // Try the fallback regions - List fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY); - if (fallbacks != null) - { - foreach (GridRegion r in fallbacks) - { - aCircuit = LaunchAgent(simConnector, r, account, avatar, session, secureSession, circuitCode, position, out reason); - if (aCircuit != null) - { - where = "safe"; - destination = r; - break; - } - } - } + m_PresenceService.LogoutAgent(session, presence.Position, presence.LookAt); + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason); + return LLFailedLoginResponse.AuthorizationProblem; - if (aCircuit == null) - { - // we tried... - m_PresenceService.LogoutAgent(session, presence.Position, presence.LookAt); - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason); - return LLFailedLoginResponse.AuthorizationProblem; - } } - // TODO: Get Friends list... // @@ -268,10 +247,11 @@ namespace OpenSim.Services.LLLoginService } } - private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out string where, out Vector3 position, out Vector3 lookAt) + private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) { m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation); + gatekeeper = null; where = "home"; position = new Vector3(128, 128, 0); lookAt = new Vector3(0, 1, 0); @@ -376,6 +356,11 @@ namespace OpenSim.Services.LLLoginService } else { + if (m_UserAgentService == null) + { + m_log.WarnFormat("[LLLOGIN SERVICE]: This llogin service is not running a user agent service, as such it can't lauch agents at foreign grids"); + return null; + } string[] parts = regionName.Split(new char[] { '@' }); if (parts.Length < 2) { @@ -390,10 +375,7 @@ namespace OpenSim.Services.LLLoginService uint port = 0; if (parts.Length > 1) UInt32.TryParse(parts[1], out port); - GridRegion region = new GridRegion(); - region.ExternalHostName = domainName; - region.HttpPort = port; - region.RegionName = regionName; + GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper); return region; } } @@ -417,10 +399,139 @@ namespace OpenSim.Services.LLLoginService } - private AgentCircuitData LaunchAgent(ISimulationService simConnector, GridRegion region, UserAccount account, - AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position, out string reason) + private GridRegion FindForeignRegion(string domainName, uint port, string regionName, out GridRegion gatekeeper) + { + gatekeeper = new GridRegion(); + gatekeeper.ExternalHostName = domainName; + gatekeeper.HttpPort = port; + gatekeeper.RegionName = regionName; + + UUID regionID; + ulong handle; + string imageURL = string.Empty, reason = string.Empty; + if (m_GatekeeperConnector.LinkRegion(gatekeeper, out regionID, out handle, out domainName, out imageURL, out reason)) + { + GridRegion destination = m_GatekeeperConnector.GetHyperlinkRegion(gatekeeper, regionID); + return destination; + } + + return null; + } + + private string hostName = string.Empty; + private int port = 0; + + private void SetHostAndPort(string url) + { + try + { + Uri uri = new Uri(url); + hostName = uri.Host; + port = uri.Port; + } + catch + { + m_log.WarnFormat("[LLLogin SERVICE]: Unable to parse GatekeeperURL {0}", url); + } + } + + private AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, + UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason) { + where = currentWhere; + ISimulationService simConnector = null; reason = string.Empty; + uint circuitCode = 0; + AgentCircuitData aCircuit = null; + + if (m_UserAgentService == null) + { + // HG standalones have both a localSimulatonDll and a remoteSimulationDll + // non-HG standalones have just a localSimulationDll + // independent login servers have just a remoteSimulationDll + if (m_LocalSimulationService != null) + simConnector = m_LocalSimulationService; + else if (m_RemoteSimulationService != null) + simConnector = m_RemoteSimulationService; + } + else // User Agent Service is on + { + if (gatekeeper == null) // login to local grid + { + if (hostName == string.Empty) + SetHostAndPort(m_GatekeeperURL); + + gatekeeper = new GridRegion(destination); + gatekeeper.ExternalHostName = hostName; + gatekeeper.HttpPort = (uint)port; + + } + else // login to foreign grid + { + } + } + + bool success = false; + + if (m_UserAgentService == null && simConnector != null) + { + circuitCode = (uint)Util.RandomClass.Next(); ; + aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position); + success = LaunchAgentDirectly(simConnector, destination, aCircuit, out reason); + if (!success && m_GridService != null) + { + // Try the fallback regions + List fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY); + if (fallbacks != null) + { + foreach (GridRegion r in fallbacks) + { + success = LaunchAgentDirectly(simConnector, r, aCircuit, out reason); + if (success) + { + where = "safe"; + destination = r; + break; + } + } + } + } + } + + if (m_UserAgentService != null) + { + circuitCode = (uint)Util.RandomClass.Next(); ; + aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position); + success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, out reason); + if (!success && m_GridService != null) + { + // Try the fallback regions + List fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY); + if (fallbacks != null) + { + foreach (GridRegion r in fallbacks) + { + success = LaunchAgentIndirectly(gatekeeper, r, aCircuit, out reason); + if (success) + { + where = "safe"; + destination = r; + break; + } + } + } + } + } + + if (success) + return aCircuit; + else + return null; + } + + private AgentCircuitData MakeAgent(GridRegion region, UserAccount account, + AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position) + { AgentCircuitData aCircuit = new AgentCircuitData(); aCircuit.AgentID = account.PrincipalID; @@ -442,10 +553,13 @@ namespace OpenSim.Services.LLLoginService aCircuit.startpos = position; SetServiceURLs(aCircuit, account); - if (simConnector.CreateAgent(region, aCircuit, 0, out reason)) - return aCircuit; + return aCircuit; - return null; + //m_UserAgentService.LoginAgentToGrid(aCircuit, GatekeeperServiceConnector, region, out reason); + //if (simConnector.CreateAgent(region, aCircuit, 0, out reason)) + // return aCircuit; + + //return null; } @@ -468,6 +582,16 @@ namespace OpenSim.Services.LLLoginService } } + private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, out string reason) + { + return simConnector.CreateAgent(region, aCircuit, (int)Constants.TeleportFlags.ViaLogin, out reason); + } + + private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, out string reason) + { + return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason); + } + #region Console Commands private void RegisterCommands() { -- cgit v1.1