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.

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

View File

@ -214,20 +214,20 @@ namespace OpenSim.ApplicationPlugins.CreateCommsManager
HGInventoryServiceClient inventoryService = new HGInventoryServiceClient(m_openSim.NetServersInfo.InventoryURL, null, false);
inventoryService.AddPlugin(m_openSim.ConfigurationSettings.StandaloneInventoryPlugin, m_openSim.ConfigurationSettings.StandaloneInventorySource);
LocalUserServices userService =
LocalUserServices localuserService =
new LocalUserServices(
m_openSim.NetServersInfo.DefaultHomeLocX, m_openSim.NetServersInfo.DefaultHomeLocY, inventoryService);
userService.AddPlugin(m_openSim.ConfigurationSettings.StandaloneUserPlugin, m_openSim.ConfigurationSettings.StandaloneUserSource);
localuserService.AddPlugin(m_openSim.ConfigurationSettings.StandaloneUserPlugin, m_openSim.ConfigurationSettings.StandaloneUserSource);
HGUserServices userService = new HGUserServices(localuserService);
HGGridServicesStandalone gridService = new HGGridServicesStandalone(m_openSim.NetServersInfo, m_httpServer, m_openSim.AssetCache, m_openSim.SceneManager);
// LocalLoginService loginService = CreateLoginService(libraryRootFolder, inventoryService, userService, gridService.LocalBackend);
m_commsManager = new HGCommunicationsStandalone(m_openSim.NetServersInfo, m_httpServer, m_openSim.AssetCache,
userService, userService, inventoryService, gridService, userService, libraryRootFolder, m_openSim.ConfigurationSettings.DumpAssetsToFile);
userService, localuserService, inventoryService, gridService, userService, libraryRootFolder, m_openSim.ConfigurationSettings.DumpAssetsToFile);
inventoryService.UserProfileCache = m_commsManager.UserProfileCacheService;
HGServices = gridService;
userService.SetCommunicationsManager(m_commsManager);
CreateGridInfoService();
}

View File

@ -103,7 +103,7 @@ namespace OpenSim.Client.Linden
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 LLStandaloneLoginService((UserManagerBase)m_firstScene.CommsManager.UserService, welcomeMessage, m_firstScene.CommsManager.InterServiceInventoryService, m_firstScene.CommsManager.NetworkServersInfo, authenticate, rootFolder, this);
m_loginService = new LLStandaloneLoginService((UserManagerBase)m_firstScene.CommsManager.UserAdminService, welcomeMessage, m_firstScene.CommsManager.InterServiceInventoryService, m_firstScene.CommsManager.NetworkServersInfo, authenticate, rootFolder, this);
httpServer.AddXmlRPCHandler("login_to_simulator", m_loginService.XmlRpcLoginMethod);

View File

@ -43,7 +43,7 @@ namespace OpenSim.Framework.Communications.Clients
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public bool DoCreateChildAgentCall(RegionInfo region, AgentCircuitData aCircuit)
public bool DoCreateChildAgentCall(RegionInfo region, AgentCircuitData aCircuit, string authKey)
{
// Eventually, we want to use a caps url instead of the agentID
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + aCircuit.AgentID + "/";
@ -54,6 +54,7 @@ namespace OpenSim.Framework.Communications.Clients
AgentCreateRequest.ContentType = "application/json";
AgentCreateRequest.Timeout = 10000;
//AgentCreateRequest.KeepAlive = false;
AgentCreateRequest.Headers.Add("Authorization", authKey);
// Fill it in
OSDMap args = null;
@ -80,7 +81,7 @@ namespace OpenSim.Framework.Communications.Clients
}
catch (Exception e)
{
m_log.WarnFormat("[OSG2]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
@ -91,7 +92,7 @@ namespace OpenSim.Framework.Communications.Clients
os = AgentCreateRequest.GetRequestStream();
os.Write(buffer, 0, strBuffer.Length); //Send it
os.Close();
//m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri);
//m_log.InfoFormat("[REST COMMS]: Posted CreateChildAgent request to remote sim {0}", uri);
}
//catch (WebException ex)
catch

View File

@ -34,5 +34,6 @@ namespace OpenSim.Framework.Communications
{
string GetNewKey(string url, UUID userID, UUID authToken);
bool VerifyKey(UUID userID, string key);
bool VerifySession(UUID iserID, UUID sessionID);
}
}

View File

@ -119,5 +119,9 @@ namespace OpenSim.Framework.Communications
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
List<FriendListItem> GetUserFriendList(UUID friendlistowner);
// This probably shouldn't be here, it belongs to IAuthentication
// But since Scenes only have IUserService references, I'm placing it here for now.
bool VerifySession(UUID userID, UUID sessionID);
}
}

View File

@ -37,6 +37,7 @@ using log4net;
using Nwc.XmlRpc;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Statistics;
@ -194,6 +195,12 @@ namespace OpenSim.Framework.Communications.Services
CreateAgent(userProfile, request);
// We need to commit the agent right here, even though the userProfile info is not complete
// at this point. There is another commit further down.
// This is for the new sessionID to be stored so that the region can check it for session authentication.
// CustomiseResponse->PrepareLoginToRegion
CommitAgent(ref userProfile);
try
{
UUID agentID = userProfile.ID;
@ -1108,5 +1115,44 @@ namespace OpenSim.Framework.Communications.Services
{
return false;
}
public XmlRpcResponse XmlRPCCheckAuthSession(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable)request.Params[0];
string authed = "FALSE";
if (requestData.Contains("avatar_uuid") && requestData.Contains("session_id"))
{
UUID guess_aid;
UUID guess_sid;
UUID.TryParse((string)requestData["avatar_uuid"], out guess_aid);
if (guess_aid == UUID.Zero)
{
return Util.CreateUnknownUserErrorResponse();
}
UUID.TryParse((string)requestData["session_id"], out guess_sid);
if (guess_sid == UUID.Zero)
{
return Util.CreateUnknownUserErrorResponse();
}
if (m_userManager.VerifySession(guess_aid, guess_sid))
{
authed = "TRUE";
}
m_log.InfoFormat("[UserManager]: CheckAuthSession TRUE for user {0}", guess_aid);
}
else
{
m_log.InfoFormat("[UserManager]: CheckAuthSession FALSE");
return Util.CreateUnknownUserErrorResponse();
}
Hashtable responseData = new Hashtable();
responseData["auth_session"] = authed;
response.Value = responseData;
return response;
}
}
}

View File

@ -178,6 +178,11 @@ namespace OpenSim.Framework.Communications.Tests
{
throw new NotImplementedException();
}
public bool VerifySession(UUID userID, UUID sessionID)
{
return true;
}
}
[Test]

View File

@ -839,6 +839,21 @@ namespace OpenSim.Framework.Communications
}
}
public bool VerifySession(UUID userID, UUID sessionID)
{
UserProfileData userProfile = GetUserProfile(userID);
if (userProfile != null && userProfile.CurrentAgent != null)
{
m_log.DebugFormat("[USERAUTH]: Verifying session {0} for {1}; current session {2}", sessionID, userID, userProfile.CurrentAgent.SessionID);
if (userProfile.CurrentAgent.SessionID == sessionID)
{
return true;
}
}
return false;
}
#endregion
}
}

View File

@ -26,6 +26,7 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
@ -819,6 +820,21 @@ namespace OpenSim.Framework
return client.Send(url, 6000);
}
/// <summary>
/// Returns an error message that the user could not be found in the database
/// </summary>
/// <returns>XML string consisting of a error element containing individual error(s)</returns>
public static XmlRpcResponse CreateUnknownUserErrorResponse()
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
responseData["error_type"] = "unknown_user";
responseData["error_desc"] = "The user requested is not in the database";
response.Value = responseData;
return response;
}
/// <summary>
/// Converts a byte array in big endian order into an ulong.
/// </summary>

View File

@ -83,6 +83,7 @@ namespace OpenSim.Grid.UserServer.Modules
m_httpServer.AddXmlRPCHandler("login_to_simulator", XmlRpcLoginMethod);
m_httpServer.AddHTTPHandler("login", ProcessHTMLLogin);
m_httpServer.AddXmlRPCHandler("set_login_params", XmlRPCSetLoginParams);
m_httpServer.AddXmlRPCHandler("check_auth_session", XmlRPCCheckAuthSession);
if (registerLLSDHandler)
{

View File

@ -109,7 +109,6 @@ namespace OpenSim.Grid.UserServer.Modules
m_httpServer.AddXmlRPCHandler("update_user_current_region", XmlRPCAtRegion);
m_httpServer.AddXmlRPCHandler("logout_of_simulator", XmlRPCLogOffUserMethodUUID);
m_httpServer.AddXmlRPCHandler("get_agent_by_uuid", XmlRPCGetAgentMethodUUID);
m_httpServer.AddXmlRPCHandler("check_auth_session", XmlRPCCheckAuthSession);
m_httpServer.AddXmlRPCHandler("update_user_profile", XmlRpcResponseXmlRPCUpdateUserProfile);
@ -133,21 +132,6 @@ namespace OpenSim.Grid.UserServer.Modules
return "OK";
}
/// <summary>
/// Returns an error message that the user could not be found in the database
/// </summary>
/// <returns>XML string consisting of a error element containing individual error(s)</returns>
public XmlRpcResponse CreateUnknownUserErrorResponse()
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
responseData["error_type"] = "unknown_user";
responseData["error_desc"] = "The user requested is not in the database";
response.Value = responseData;
return response;
}
public XmlRpcResponse AvatarPickerListtoXmlRPCResponse(UUID queryID, List<AvatarPickerAvatar> returnUsers)
{
XmlRpcResponse response = new XmlRpcResponse();
@ -278,7 +262,7 @@ namespace OpenSim.Grid.UserServer.Modules
string query = (string)requestData["avatar_name"];
if (null == query)
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
// Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
@ -289,17 +273,17 @@ namespace OpenSim.Grid.UserServer.Modules
userProfile = m_userDataBaseService.GetUserProfile(querysplit[0], querysplit[1]);
if (userProfile == null)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
}
else
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
}
else
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
return ProfileToXmlRPCResponse(userProfile);
@ -322,17 +306,17 @@ namespace OpenSim.Grid.UserServer.Modules
}
catch (FormatException)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
if (userProfile == null)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
}
else
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
return ProfileToXmlRPCResponse(userProfile);
@ -353,20 +337,20 @@ namespace OpenSim.Grid.UserServer.Modules
if (guess == UUID.Zero)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
userProfile = m_userDataBaseService.GetUserProfile(guess);
if (userProfile == null)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
// no agent???
if (userProfile.CurrentAgent == null)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
Hashtable responseData = new Hashtable();
@ -381,53 +365,12 @@ namespace OpenSim.Grid.UserServer.Modules
}
else
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
return response;
}
public XmlRpcResponse XmlRPCCheckAuthSession(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable)request.Params[0];
UserProfileData userProfile;
string authed = "FALSE";
if (requestData.Contains("avatar_uuid") && requestData.Contains("session_id"))
{
UUID guess_aid;
UUID guess_sid;
UUID.TryParse((string)requestData["avatar_uuid"], out guess_aid);
if (guess_aid == UUID.Zero)
{
return CreateUnknownUserErrorResponse();
}
UUID.TryParse((string)requestData["session_id"], out guess_sid);
if (guess_sid == UUID.Zero)
{
return CreateUnknownUserErrorResponse();
}
userProfile = m_userDataBaseService.GetUserProfile(guess_aid);
if (userProfile != null && userProfile.CurrentAgent != null &&
userProfile.CurrentAgent.SessionID == guess_sid)
{
authed = "TRUE";
}
m_log.InfoFormat("[UserManager]: CheckAuthSession TRUE for user {0}", guess_aid);
}
else
{
m_log.InfoFormat("[UserManager]: CheckAuthSession FALSE");
return CreateUnknownUserErrorResponse();
}
Hashtable responseData = new Hashtable();
responseData["auth_session"] = authed;
response.Value = responseData;
return response;
}
public XmlRpcResponse XmlRpcResponseXmlRPCUpdateUserProfile(XmlRpcRequest request)
{
m_log.Debug("[UserManager]: Got request to update user profile");
@ -437,14 +380,14 @@ namespace OpenSim.Grid.UserServer.Modules
if (!requestData.Contains("avatar_uuid"))
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
UUID UserUUID = new UUID((string)requestData["avatar_uuid"]);
UserProfileData userProfile = m_userDataBaseService.GetUserProfile(UserUUID);
if (null == userProfile)
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
// don't know how yet.
if (requestData.Contains("AllowPublish"))
@ -656,7 +599,7 @@ namespace OpenSim.Grid.UserServer.Modules
}
else
{
return CreateUnknownUserErrorResponse();
return Util.CreateUnknownUserErrorResponse();
}
return response;

View File

@ -59,6 +59,7 @@ namespace OpenSim.Region.Communications.Hypergrid
// The HG InventoryService always uses secure handlers
HGInventoryServiceClient invService = new HGInventoryServiceClient(serversInfo.InventoryURL, this.m_userProfileCacheService, true);
invService.UserProfileCache = m_userProfileCacheService;
AddSecureInventoryService(invService);
m_defaultInventoryHost = invService.Host;
if (SecureInventoryService != null)

View File

@ -62,7 +62,7 @@ namespace OpenSim.Region.Communications.Hypergrid
{
_inventoryServerUrl = HGNetworkServersInfo.ServerURI(inventoryServerUrl);
//m_Uri = new Uri(_inventoryServerUrl);
m_userProfileCache = userProfileCacheService;
//m_userProfileCache = userProfileCacheService;
m_gridmode = gridmode;
}
@ -506,6 +506,9 @@ namespace OpenSim.Region.Communications.Hypergrid
private bool IsLocalStandaloneUser(UUID userID)
{
if (m_userProfileCache == null)
return false;
CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID);
if (uinfo == null)
return true;
@ -522,6 +525,7 @@ namespace OpenSim.Region.Communications.Hypergrid
private string GetUserInventoryURI(UUID userID)
{
string invURI = _inventoryServerUrl;
CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID);
if ((uinfo == null) || (uinfo.UserProfile == null))
return invURI;

View File

@ -31,7 +31,10 @@ using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Communications.Clients;
using OpenSim.Region.Communications.OGS1;
using OpenSim.Region.Communications.Local;
namespace OpenSim.Region.Communications.Hypergrid
{
@ -40,32 +43,30 @@ namespace OpenSim.Region.Communications.Hypergrid
/// so it always fails for foreign users.
/// Later it needs to talk with the foreign users' user servers.
/// </summary>
public class HGUserServices : IUserService, IAvatarService, IMessagingService
public class HGUserServices : OGS1UserServices
{
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private HGCommunicationsGridMode m_parent;
private OGS1UserServices m_remoteUserServices;
//private CommunicationsManager m_parent;
//private OGS1UserServices m_remoteUserServices;
private LocalUserServices m_localUserServices;
public HGUserServices(HGCommunicationsGridMode parent)
// Constructor called when running in grid mode
public HGUserServices(CommunicationsManager parent)
: base(parent)
{
//m_parent = parent;
m_remoteUserServices = new OGS1UserServices(parent);
}
public UserProfileData ConvertXMLRPCDataToUserProfile(Hashtable data)
// Constructor called when running in standalone
public HGUserServices(LocalUserServices local)
{
return m_remoteUserServices.ConvertXMLRPCDataToUserProfile(data);
m_localUserServices = local;
}
public UserProfileData GetUserProfile(Uri uri)
// Called for standalone mode only, to set up the communications manager
public void SetCommunicationsManager(CommunicationsManager parent)
{
throw new System.NotImplementedException();
}
public Uri GetUserUri(UserProfileData userProfile)
{
throw new NotImplementedException();
m_commsManager = parent;
}
/// <summary>
@ -73,25 +74,15 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="avatarID"></param>
/// <returns>null if the request fails</returns>
public UserAgentData GetAgentByUUID(UUID userId)
public override UserAgentData GetAgentByUUID(UUID userId)
{
return m_remoteUserServices.GetAgentByUUID(userId);
string url = string.Empty;
if ((m_localUserServices != null) && !IsForeignUser(userId, out url))
return m_localUserServices.GetAgentByUUID(userId);
return base.GetAgentByUUID(userId);
}
public AvatarAppearance ConvertXMLRPCDataToAvatarAppearance(Hashtable data)
{
return m_remoteUserServices.ConvertXMLRPCDataToAvatarAppearance(data);
}
public List<AvatarPickerAvatar> ConvertXMLRPCDataToAvatarPickerList(UUID queryID, Hashtable data)
{
return m_remoteUserServices.ConvertXMLRPCDataToAvatarPickerList(queryID, data);
}
public List<FriendListItem> ConvertXMLRPCDataToFriendListItemList(Hashtable data)
{
return m_remoteUserServices.ConvertXMLRPCDataToFriendListItemList(data);
}
/// <summary>
/// Logs off a user on the user server
@ -101,9 +92,13 @@ namespace OpenSim.Region.Communications.Hypergrid
/// <param name="regionhandle">regionhandle</param>
/// <param name="position">final position</param>
/// <param name="lookat">final lookat</param>
public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat)
public override void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat)
{
m_remoteUserServices.LogOffUser(userid, regionid, regionhandle, position, lookat);
string url = string.Empty;
if ((m_localUserServices != null) && !IsForeignUser(userid, out url))
m_localUserServices.LogOffUser(userid, regionid, regionhandle, position, lookat);
else
base.LogOffUser(userid, regionid, regionhandle, position, lookat);
}
/// <summary>
@ -115,19 +110,29 @@ namespace OpenSim.Region.Communications.Hypergrid
/// <param name="posx">final position x</param>
/// <param name="posy">final position y</param>
/// <param name="posz">final position z</param>
public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz)
public override void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz)
{
m_remoteUserServices.LogOffUser(userid, regionid, regionhandle, posx, posy, posz);
string url = string.Empty;
if ((m_localUserServices != null) && !IsForeignUser(userid, out url))
m_localUserServices.LogOffUser(userid, regionid, regionhandle, posx, posy, posz);
else
base.LogOffUser(userid, regionid, regionhandle, posx, posy, posz);
}
public UserProfileData GetUserProfile(string firstName, string lastName)
public override UserProfileData GetUserProfile(string firstName, string lastName)
{
if (m_localUserServices != null)
return m_localUserServices.GetUserProfile(firstName, lastName);
return GetUserProfile(firstName + " " + lastName);
}
public List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(UUID queryID, string query)
public override List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(UUID queryID, string query)
{
return m_remoteUserServices.GenerateAgentPickerRequestResponse(queryID, query);
if (m_localUserServices != null)
return m_localUserServices.GenerateAgentPickerRequestResponse(queryID, query);
return base.GenerateAgentPickerRequestResponse(queryID, query);
}
/// <summary>
@ -135,9 +140,11 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="avatarID"></param>
/// <returns>null if the request fails</returns>
public UserProfileData GetUserProfile(string name)
public override UserProfileData GetUserProfile(string name)
{
return m_remoteUserServices.GetUserProfile(name);
// This doesn't exist in LocalUserServices
return base.GetUserProfile(name);
}
/// <summary>
@ -145,14 +152,24 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="avatarID"></param>
/// <returns>null if the request fails</returns>
public UserProfileData GetUserProfile(UUID avatarID)
public override UserProfileData GetUserProfile(UUID avatarID)
{
return m_remoteUserServices.GetUserProfile(avatarID);
string url = string.Empty;
// Unfortunately we can't query for foreigners here,
// because we'll end up in an infinite loop...
//if ((m_localUserServices != null) && (!IsForeignUser(avatarID, out url)))
if (m_localUserServices != null)
return m_localUserServices.GetUserProfile(avatarID);
return base.GetUserProfile(avatarID);
}
public void ClearUserAgent(UUID avatarID)
public override void ClearUserAgent(UUID avatarID)
{
m_remoteUserServices.ClearUserAgent(avatarID);
if (m_localUserServices != null)
m_localUserServices.ClearUserAgent(avatarID);
else
base.ClearUserAgent(avatarID);
}
/// <summary>
@ -160,9 +177,12 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="uuid"></param>
/// <returns></returns>
public UserProfileData SetupMasterUser(string firstName, string lastName)
public override UserProfileData SetupMasterUser(string firstName, string lastName)
{
return m_remoteUserServices.SetupMasterUser(firstName, lastName);
if (m_localUserServices != null)
return m_localUserServices.SetupMasterUser(firstName, lastName);
return base.SetupMasterUser(firstName, lastName);
}
/// <summary>
@ -170,9 +190,12 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="uuid"></param>
/// <returns></returns>
public UserProfileData SetupMasterUser(string firstName, string lastName, string password)
public override UserProfileData SetupMasterUser(string firstName, string lastName, string password)
{
return m_remoteUserServices.SetupMasterUser(firstName, lastName, password);
if (m_localUserServices != null)
return m_localUserServices.SetupMasterUser(firstName, lastName, password);
return base.SetupMasterUser(firstName, lastName, password);
}
/// <summary>
@ -180,36 +203,47 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="uuid"></param>
/// <returns></returns>
public UserProfileData SetupMasterUser(UUID uuid)
public override UserProfileData SetupMasterUser(UUID uuid)
{
return m_remoteUserServices.SetupMasterUser(uuid);
if (m_localUserServices != null)
return m_localUserServices.SetupMasterUser(uuid);
return base.SetupMasterUser(uuid);
}
public UUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY)
public override bool ResetUserPassword(string firstName, string lastName, string newPassword)
{
return m_remoteUserServices.AddUserProfile(firstName, lastName, pass, regX, regY);
if (m_localUserServices != null)
return m_localUserServices.ResetUserPassword(firstName, lastName, newPassword);
else
return base.ResetUserPassword(firstName, lastName, newPassword);
}
public bool ResetUserPassword(string firstName, string lastName, string newPassword)
{
return m_remoteUserServices.ResetUserPassword(firstName, lastName, newPassword);
}
public bool UpdateUserProfile(UserProfileData userProfile)
public override bool UpdateUserProfile(UserProfileData userProfile)
{
return m_remoteUserServices.UpdateUserProfile(userProfile);
string url = string.Empty;
if ((m_localUserServices != null) && (!IsForeignUser(userProfile.ID, out url)))
return m_localUserServices.UpdateUserProfile(userProfile);
return base.UpdateUserProfile(userProfile);
}
#region IUserServices Friend Methods
// NOTE: We're still not dealing with foreign user friends
/// <summary>
/// Adds a new friend to the database for XUser
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being added to</param>
/// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
public override void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
{
m_remoteUserServices.AddNewUserFriend(friendlistowner, friend, perms);
if (m_localUserServices != null)
m_localUserServices.AddNewUserFriend(friendlistowner, friend, perms);
else
base.AddNewUserFriend(friendlistowner, friend, perms);
}
/// <summary>
@ -217,9 +251,12 @@ namespace OpenSim.Region.Communications.Hypergrid
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The Ex-friend agent</param>
public void RemoveUserFriend(UUID friendlistowner, UUID friend)
public override void RemoveUserFriend(UUID friendlistowner, UUID friend)
{
m_remoteUserServices.RemoveUserFriend(friend, friend);
if (m_localUserServices != null)
m_localUserServices.RemoveUserFriend(friendlistowner, friend);
else
base.RemoveUserFriend(friend, friend);
}
/// <summary>
@ -228,39 +265,79 @@ namespace OpenSim.Region.Communications.Hypergrid
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The agent that is getting or loosing permissions</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
public override void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
{
m_remoteUserServices.UpdateUserFriendPerms(friendlistowner, friend, perms);
if (m_localUserServices != null)
m_localUserServices.UpdateUserFriendPerms(friendlistowner, friend, perms);
else
base.UpdateUserFriendPerms(friendlistowner, friend, perms);
}
/// <summary>
/// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for UUID friendslistowner
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
public List<FriendListItem> GetUserFriendList(UUID friendlistowner)
public override List<FriendListItem> GetUserFriendList(UUID friendlistowner)
{
return m_remoteUserServices.GetUserFriendList(friendlistowner);
if (m_localUserServices != null)
return m_localUserServices.GetUserFriendList(friendlistowner);
return base.GetUserFriendList(friendlistowner);
}
#endregion
/// Appearance
public AvatarAppearance GetUserAppearance(UUID user)
public override AvatarAppearance GetUserAppearance(UUID user)
{
return m_remoteUserServices.GetUserAppearance(user);
string url = string.Empty;
if ((m_localUserServices != null) && (!IsForeignUser(user, out url)))
return m_localUserServices.GetUserAppearance(user);
else
return base.GetUserAppearance(user);
}
public void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
public override void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
{
m_remoteUserServices.UpdateUserAppearance(user, appearance);
string url = string.Empty;
if ((m_localUserServices != null) && (!IsForeignUser(user, out url)))
m_localUserServices.UpdateUserAppearance(user, appearance);
else
base.UpdateUserAppearance(user, appearance);
}
#region IMessagingService
public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos(List<UUID> uuids)
public override Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos(List<UUID> uuids)
{
return m_remoteUserServices.GetFriendRegionInfos(uuids);
if (m_localUserServices != null)
return m_localUserServices.GetFriendRegionInfos(uuids);
return base.GetFriendRegionInfos(uuids);
}
#endregion
protected override string GetUserServerURL(UUID userID)
{
string serverURL = string.Empty;
if (IsForeignUser(userID, out serverURL))
return serverURL;
return m_commsManager.NetworkServersInfo.UserURL;
}
private bool IsForeignUser(UUID userID, out string userServerURL)
{
userServerURL = string.Empty;
CachedUserInfo uinfo = m_commsManager.UserProfileCacheService.GetUserDetails(userID);
if (uinfo != null)
{
if (!HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile))
{
userServerURL = ((ForeignUserProfileData)(uinfo.UserProfile)).UserServerURI;
return true;
}
}
return false;
}
}
}

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);
}
}

View File

@ -40,6 +40,7 @@ using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Communications.Clients;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes.Scripting;
@ -2372,64 +2373,80 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="agent"></param>
public bool NewUserConnection(AgentCircuitData agent)
{
CapsModule.NewUserConnection(agent);
bool goodUserConnection = AuthenticateUser(agent);
ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
if (sp != null)
if (goodUserConnection)
{
m_log.DebugFormat(
"[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
agent.AgentID, RegionInfo.RegionName);
CapsModule.NewUserConnection(agent);
sp.AdjustKnownSeeds();
ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
if (sp != null)
{
m_log.DebugFormat(
"[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
agent.AgentID, RegionInfo.RegionName);
sp.AdjustKnownSeeds();
return true;
}
// Don't disable this log message - it's too helpful
m_log.InfoFormat(
"[CONNECTION BEGIN]: Region {0} told of incoming client {1} {2} {3} (circuit code {4})",
RegionInfo.RegionName, agent.firstname, agent.lastname, agent.AgentID, agent.circuitcode);
if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
{
m_log.WarnFormat(
"[CONNECTION BEGIN]: Incoming user {0} at {1} is on the region banlist",
agent.AgentID, RegionInfo.RegionName);
//return false;
}
CapsModule.AddCapsHandler(agent.AgentID);
if (!agent.child)
{
// Honor parcel landing type and position.
ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
if (land != null)
{
if (land.landData.LandingType == (byte)1 && land.landData.UserLocation != Vector3.Zero)
{
agent.startpos = land.landData.UserLocation;
}
}
}
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
// rewrite session_id
CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID);
if (userinfo != null)
{
userinfo.SessionID = agent.SessionID;
}
else
{
m_log.WarnFormat(
"[CONNECTION BEGIN]: We couldn't find a User Info record for {0}. This is usually an indication that the UUID we're looking up is invalid", agent.AgentID);
}
return true;
}
// Don't disable this log message - it's too helpful
m_log.InfoFormat(
"[CONNECTION BEGIN]: Region {0} told of incoming client {1} {2} {3} (circuit code {4})",
RegionInfo.RegionName, agent.firstname, agent.lastname, agent.AgentID, agent.circuitcode);
if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
{
m_log.WarnFormat(
"[CONNECTION BEGIN]: Incoming user {0} at {1} is on the region banlist",
agent.AgentID, RegionInfo.RegionName);
//return false;
}
CapsModule.AddCapsHandler(agent.AgentID);
if (!agent.child)
{
// Honor parcel landing type and position.
ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
if (land != null)
{
if (land.landData.LandingType == (byte)1 && land.landData.UserLocation != Vector3.Zero)
{
agent.startpos = land.landData.UserLocation;
}
}
}
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
// rewrite session_id
CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID);
if (userinfo != null)
{
userinfo.SessionID = agent.SessionID;
}
else
{
m_log.WarnFormat(
"[CONNECTION BEGIN]: We couldn't find a User Info record for {0}. This is usually an indication that the UUID we're looking up is invalid", agent.AgentID);
m_log.WarnFormat("[CONNECTION BEGIN]: failed to authenticate user {0} {1}. Denying connection.", agent.firstname, agent.lastname);
return false;
}
}
return true;
public virtual bool AuthenticateUser(AgentCircuitData agent)
{
bool result = CommsManager.UserService.VerifySession(agent.AgentID, agent.SessionID);
m_log.Debug("[CONNECTION BEGIN]: User authentication returned " + result);
return result;
}
public void UpdateCircuitData(AgentCircuitData data)