Adds session authentication upon NewUserConnections. Adds user key authentication (in safemode only) upon CreateChildAgents. All of this for Hypergrid users too. This addresses assorted spoofing vulnerabilities.

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

View File

@@ -59,6 +59,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected RegionToRegionClient m_regionClient;
protected bool m_safemode;
protected IPAddress m_thisIP;
#region IRegionModule
public virtual void Initialise(Scene scene, IConfigSource config)
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{
m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module");
m_enabled = true;
if (config.Configs["Hypergrid"] != null)
m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false);
InitOnce(scene);
}
}
@@ -117,6 +123,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
m_commsManager = scene.CommsManager;
m_aScene = scene;
m_regionClient = new RegionToRegionClient(m_aScene);
m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName);
}
protected virtual void AddHTTPHandlers()
@@ -148,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{
m_regionClient.SendUserInformation(regInfo, aCircuit);
return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit);
return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None");
}
//else
// m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
@@ -331,6 +338,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
responsedata["content_type"] = "text/html";
responsedata["keepalive"] = false;
UUID agentID;
string action;
ulong regionHandle;
@@ -378,6 +386,28 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
{
if (m_safemode)
{
// Authentication
string authority = string.Empty;
string authToken = string.Empty;
if (!GetAuthentication(request, out authority, out authToken))
{
m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]);
responsedata["int_response_code"] = 403;
responsedata["str_response_string"] = "Forbidden";
return ;
}
if (!VerifyKey(id, authority, authToken))
{
m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]);
responsedata["int_response_code"] = 403;
responsedata["str_response_string"] = "Forbidden";
return ;
}
m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id);
}
OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
if (args == null)
{
@@ -793,6 +823,53 @@ namespace OpenSim.Region.CoreModules.Communications.REST
}
}
public static bool GetAuthentication(Hashtable request, out string authority, out string authKey)
{
authority = string.Empty;
authKey = string.Empty;
Uri authUri;
Hashtable headers = (Hashtable)request["headers"];
// Authorization keys look like this:
// http://orgrid.org:8002/<uuid>
if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None")
{
if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri))
{
authority = authUri.Authority;
authKey = authUri.PathAndQuery.Trim('/');
m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey);
return true;
}
else
m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]);
}
else
m_log.Debug("[REST COMMS]: Authorization header not found");
return false;
}
bool VerifyKey(UUID userID, string authority, string key)
{
string[] parts = authority.Split(':');
IPAddress ipaddr = IPAddress.None;
uint port = 0;
if (parts.Length <= 2)
ipaddr = Util.GetHostFromDNS(parts[0]);
if (parts.Length == 2)
UInt32.TryParse(parts[1], out port);
// local authority (standalone), local call
if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port))
return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key);
// remote call
else
return AuthClient.VerifyKey("http://" + authority, userID, key);
}
#endregion Misc
protected class RegionToRegionClient : RegionClient

View File

@@ -93,7 +93,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
m_inventoryService = new HGInventoryService(m_inventoryBase,
((AssetServerBase)m_scene.CommsManager.AssetCache.AssetServer).AssetProviderPlugin,
(UserManagerBase)m_scene.CommsManager.UserService, m_scene.CommsManager.HttpServer,
(UserManagerBase)m_scene.CommsManager.UserAdminService, m_scene.CommsManager.HttpServer,
m_scene.CommsManager.NetworkServersInfo.InventoryURL);
AddHttpHandlers(m_scene.CommsManager.HttpServer);

View File

@@ -104,11 +104,12 @@ namespace OpenSim.Region.CoreModules.Hypergrid
IHttpServer httpServer = m_firstScene.CommsManager.HttpServer;
//TODO: fix the casting of the user service, maybe by registering the userManagerBase with scenes, or refactoring so we just need a IUserService reference
m_loginService = new HGLoginAuthService((UserManagerBase)m_firstScene.CommsManager.UserService, welcomeMessage, m_firstScene.CommsManager.InterServiceInventoryService, m_firstScene.CommsManager.NetworkServersInfo, authenticate, rootFolder, this);
m_loginService = new HGLoginAuthService((UserManagerBase)m_firstScene.CommsManager.UserAdminService, welcomeMessage, m_firstScene.CommsManager.InterServiceInventoryService, m_firstScene.CommsManager.NetworkServersInfo, authenticate, rootFolder, this);
httpServer.AddXmlRPCHandler("hg_login", m_loginService.XmlRpcLoginMethod);
httpServer.AddXmlRPCHandler("hg_new_auth_key", m_loginService.XmlRpcGenerateKeyMethod);
httpServer.AddXmlRPCHandler("hg_verify_auth_key", m_loginService.XmlRpcVerifyKeyMethod);
httpServer.AddXmlRPCHandler("check_auth_session", m_loginService.XmlRPCCheckAuthSession);
}
}