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.

bullet-2.82
Diva Canto 2014-05-03 17:13:53 -07:00
parent 3a2c099169
commit 5a10da3ee8
4 changed files with 48 additions and 5 deletions

View File

@ -44,15 +44,17 @@ namespace OpenSim.Groups
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI; private string m_ServerURI;
private string m_SecretKey;
private object m_Lock = new object(); private object m_Lock = new object();
public GroupsServiceRemoteConnector(string url) public GroupsServiceRemoteConnector(string url, string secret)
{ {
m_ServerURI = url; m_ServerURI = url;
if (!m_ServerURI.EndsWith("/")) if (!m_ServerURI.EndsWith("/"))
m_ServerURI += "/"; 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, 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<string, object> MakeRequest(string method, Dictionary<string, object> sendData) private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
{ {
sendData["METHOD"] = method; sendData["METHOD"] = method;
if (m_SecretKey != string.Empty)
sendData["KEY"] = m_SecretKey;
string reply = string.Empty; string reply = string.Empty;
lock (m_Lock) lock (m_Lock)

View File

@ -77,7 +77,8 @@ namespace OpenSim.Groups
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) 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)); 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<Scene>(); m_Scenes = new List<Scene>();
} }

View File

@ -52,14 +52,24 @@ namespace OpenSim.Groups
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) : public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName) base(config, server, configName)
{ {
string key = string.Empty;
if (configName != String.Empty) if (configName != String.Empty)
m_ConfigName = configName; m_ConfigName = configName;
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_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); 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 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private GroupsService m_GroupsService; private GroupsService m_GroupsService;
private string m_SecretKey = String.Empty;
public GroupsServicePostHandler(GroupsService service) : public GroupsServicePostHandler(GroupsService service, string key) :
base("POST", "/groups") base("POST", "/groups")
{ {
m_GroupsService = service; m_GroupsService = service;
m_SecretKey = key;
} }
protected override byte[] ProcessRequest(string path, Stream requestData, protected override byte[] ProcessRequest(string path, Stream requestData,
@ -96,6 +108,20 @@ namespace OpenSim.Groups
string method = request["METHOD"].ToString(); string method = request["METHOD"].ToString();
request.Remove("METHOD"); 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); m_log.DebugFormat("[Groups.Handler]: {0}", method);
switch (method) switch (method)
{ {
@ -784,6 +810,14 @@ namespace OpenSim.Groups
string xmlString = ServerUtils.BuildXmlResponse(result); string xmlString = ServerUtils.BuildXmlResponse(result);
return Util.UTF8NoBomEncoding.GetBytes(xmlString); return Util.UTF8NoBomEncoding.GetBytes(xmlString);
} }
private byte[] FailureResult(string reason)
{
Dictionary<string, object> result = new Dictionary<string, object>();
NullResult(result, reason);
string xmlString = ServerUtils.BuildXmlResponse(result);
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
#endregion #endregion
} }
} }

View File

@ -996,6 +996,10 @@
;; Used for V2 in HG only. If standalone, set this to local; if grided sim, set this to remote ;; Used for V2 in HG only. If standalone, set this to local; if grided sim, set this to remote
; LocalService = local ; 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} {} ;# {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 ;; URI for the groups services of this grid
;; e.g. http://yourxmlrpcserver.com/xmlrpc.php for Flotsam XmlRpc ;; e.g. http://yourxmlrpcserver.com/xmlrpc.php for Flotsam XmlRpc