From 5a10da3ee89934e366c1d69833b81605dbc35017 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 3 May 2014 17:13:53 -0700 Subject: [PATCH] Added a optional key between the group remote connectors, sim and service. This allows for more secure group services, to be used by collections of mutually-trusting grids. --- .../Remote/GroupsServiceRemoteConnector.cs | 8 +++- .../GroupsServiceRemoteConnectorModule.cs | 3 +- .../Remote/GroupsServiceRobustConnector.cs | 38 ++++++++++++++++++- bin/OpenSim.ini.example | 4 ++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs index 67402a2214..1425a23c39 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs @@ -44,15 +44,17 @@ namespace OpenSim.Groups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private string m_ServerURI; + private string m_SecretKey; private object m_Lock = new object(); - public GroupsServiceRemoteConnector(string url) + public GroupsServiceRemoteConnector(string url, string secret) { m_ServerURI = url; if (!m_ServerURI.EndsWith("/")) m_ServerURI += "/"; - m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI); + m_SecretKey = secret; + m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, secret key {1}", m_ServerURI, m_SecretKey); } public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, @@ -654,6 +656,8 @@ namespace OpenSim.Groups private Dictionary MakeRequest(string method, Dictionary sendData) { sendData["METHOD"] = method; + if (m_SecretKey != string.Empty) + sendData["KEY"] = m_SecretKey; string reply = string.Empty; lock (m_Lock) diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs index d3de0e8975..5fb3c19883 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs @@ -77,7 +77,8 @@ namespace OpenSim.Groups if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url)); - m_GroupsService = new GroupsServiceRemoteConnector(url); + string secret = groupsConfig.GetString("SecretKey", string.Empty); + m_GroupsService = new GroupsServiceRemoteConnector(url, secret); m_Scenes = new List(); } diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index 616afa9061..828965f9ae 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -52,14 +52,24 @@ namespace OpenSim.Groups public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) : base(config, server, configName) { + string key = string.Empty; if (configName != String.Empty) m_ConfigName = configName; m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName); + IConfig groupsConfig = config.Configs[m_ConfigName]; + if (groupsConfig != null) + { + key = groupsConfig.GetString("SecretKey", string.Empty); + m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key); + } + else + m_log.WarnFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName); + m_GroupsService = new GroupsService(config); - server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService)); + server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, key)); } } @@ -68,11 +78,13 @@ namespace OpenSim.Groups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private GroupsService m_GroupsService; + private string m_SecretKey = String.Empty; - public GroupsServicePostHandler(GroupsService service) : + public GroupsServicePostHandler(GroupsService service, string key) : base("POST", "/groups") { m_GroupsService = service; + m_SecretKey = key; } protected override byte[] ProcessRequest(string path, Stream requestData, @@ -96,6 +108,20 @@ namespace OpenSim.Groups string method = request["METHOD"].ToString(); request.Remove("METHOD"); + if (!String.IsNullOrEmpty(m_SecretKey)) // Verification required + { + // Sender didn't send key + if (!request.ContainsKey("KEY") || (request["KEY"] == null)) + return FailureResult("This service requires a secret key"); + + // Sender sent wrong key + if (!m_SecretKey.Equals(request["KEY"])) + return FailureResult("Provided key does not match existing one"); + + // OK, key matches. Remove it. + request.Remove("KEY"); + } + m_log.DebugFormat("[Groups.Handler]: {0}", method); switch (method) { @@ -784,6 +810,14 @@ namespace OpenSim.Groups string xmlString = ServerUtils.BuildXmlResponse(result); return Util.UTF8NoBomEncoding.GetBytes(xmlString); } + + private byte[] FailureResult(string reason) + { + Dictionary result = new Dictionary(); + NullResult(result, reason); + string xmlString = ServerUtils.BuildXmlResponse(result); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); + } #endregion } } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 1395d72124..8742313aeb 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -996,6 +996,10 @@ ;; Used for V2 in HG only. If standalone, set this to local; if grided sim, set this to remote ; LocalService = local + ;# {SecretKey} {ServicesConnectorModule:Groups Remote Service Connector} {Secret key between sim and remote group service} {} "" + ;; Used for V2 in Remote only. + ; SecretKey = "" + ;# {GroupsServerURI} {Module:GroupsModule (ServicesConnectorModule:Groups Remote Service Connector or (ServicesConnectorModule:Groups HG Service Connector and LocalService:remote))} {Groups Server URI} {} ;; URI for the groups services of this grid ;; e.g. http://yourxmlrpcserver.com/xmlrpc.php for Flotsam XmlRpc