From: Alan M Webb <alan_webb@us.ibm.com>

Added support for access control lists.
  Scene: Added test to AddNewClient for an entry in the access
         list when connecting to a region with limited access.
  EstateSettings: Added an HasAccess(UUID) property to test for
         an entry in the estate's access list.
  RemoteAdmin: Add RPC calls for admin_acl_list, clear, add,
         and remove.
0.6.5-rc1
Dr Scofield 2009-04-27 11:51:25 +00:00
parent 8dbcfc70bf
commit 515e62dc2f
3 changed files with 346 additions and 39 deletions

View File

@ -102,19 +102,26 @@ namespace OpenSim.ApplicationPlugins.RemoteController
Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>(); Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>();
availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod;
availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod; availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod;
availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
availableMethods["admin_broadcast"] = XmlRpcAlertMethod; availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
availableMethods["admin_restart"] = XmlRpcRestartMethod; availableMethods["admin_restart"] = XmlRpcRestartMethod;
availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
// User management
availableMethods["admin_create_user"] = XmlRpcCreateUserMethod; availableMethods["admin_create_user"] = XmlRpcCreateUserMethod;
availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod; availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod;
availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod; availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod;
availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod; availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod;
// Region state management
availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod; availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod;
availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod; availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod;
availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod; availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod;
availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod; availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod;
availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; // Estate access list management
availableMethods["admin_acl_clear"] = XmlRpcAccessListClear;
availableMethods["admin_acl_add"] = XmlRpcAccessListAdd;
availableMethods["admin_acl_remove"] = XmlRpcAccessListRemove;
availableMethods["admin_acl_list"] = XmlRpcAccessListList;
// Either enable full remote functionality or just selected features // Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all"); string enabledMethods = m_config.GetString("enabled_methods", "all");
@ -1496,8 +1503,287 @@ namespace OpenSim.ApplicationPlugins.RemoteController
return response; return response;
} }
public XmlRpcResponse XmlRpcAccessListClear(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List Clear Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(requiredPassword) &&
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
Scene s = m_app.SceneManager.CurrentScene;
s.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Access List Clear Request: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List Clear Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListAdd(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List Add Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(requiredPassword) &&
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
int addk = 0;
if(requestData.Contains("users"))
{
UserProfileCacheService ups = m_app.CommunicationsManager.UserProfileCacheService;
Scene s = m_app.SceneManager.CurrentScene;
Hashtable users = (Hashtable) requestData["users"];
List<UUID> uuids = new List<UUID>();
foreach(string name in users.Values)
{
string[] parts = name.Split();
uuids.Add(ups.GetUserDetails(parts[0],parts[1]).UserProfile.ID);
}
List<UUID> acl = new List<UUID>(s.RegionInfo.EstateSettings.EstateAccess);
foreach(UUID uuid in uuids)
{
if(!acl.Contains(uuid))
{
acl.Add(uuid);
addk++;
}
}
s.RegionInfo.EstateSettings.EstateAccess = acl.ToArray();
}
responseData["added"] = addk;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Access List Add Request: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List Add Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListRemove(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List Remove Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(requiredPassword) &&
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
int remk = 0;
if(requestData.Contains("users"))
{
UserProfileCacheService ups = m_app.CommunicationsManager.UserProfileCacheService;
Scene s = m_app.SceneManager.CurrentScene;
Hashtable users = (Hashtable) requestData["users"];
List<UUID> uuids = new List<UUID>();
foreach(string name in users.Values)
{
string[] parts = name.Split();
uuids.Add(ups.GetUserDetails(parts[0],parts[1]).UserProfile.ID);
}
List<UUID> acl = new List<UUID>(s.RegionInfo.EstateSettings.EstateAccess);
foreach(UUID uuid in uuids)
{
if(acl.Contains(uuid))
{
acl.Remove(uuid);
remk++;
}
}
s.RegionInfo.EstateSettings.EstateAccess = acl.ToArray();
}
responseData["added"] = remk;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Access List Remove Request: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List Remove Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListList(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List List Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(requiredPassword) &&
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
Scene s = m_app.SceneManager.CurrentScene;
UUID[] acl = s.RegionInfo.EstateSettings.EstateAccess;
Hashtable users = new Hashtable();
foreach(UUID user in acl)
{
users[user.ToString()] =
m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails(user).UserProfile.Name;
}
responseData["users"] = users;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Acces List List: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List List Request complete");
return response;
}
public void Dispose() public void Dispose()
{ {
} }
} }
} }

View File

@ -358,6 +358,11 @@ namespace OpenSim.Framework
l_EstateBans.Remove(ban); l_EstateBans.Remove(ban);
} }
public bool HasAccess(UUID user)
{
return l_EstateAccess.Contains(user);
}
public void loadConfigurationOptions() public void loadConfigurationOptions()
{ {
configMember.addConfigurationOption("billable_factor", configMember.addConfigurationOption("billable_factor",

View File

@ -1846,11 +1846,25 @@ namespace OpenSim.Region.Framework.Scenes
public override void AddNewClient(IClientAPI client) public override void AddNewClient(IClientAPI client)
{ {
if (m_regInfo.EstateSettings.IsBanned(client.AgentId)) bool welcome = true;
if(m_regInfo.EstateSettings.IsBanned(client.AgentId))
{ {
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
client.AgentId, client.FirstName, client.LastName, RegionInfo.RegionName); client.AgentId, client.FirstName, client.LastName, RegionInfo.RegionName);
client.SendAlertMessage("Denied access to region " + RegionInfo.RegionName + ". You have been banned from that region."); client.SendAlertMessage("Denied access to region " + RegionInfo.RegionName + ". You have been banned from that region.");
welcome = false;
}
else if (!m_regInfo.EstateSettings.PublicAccess && !m_regInfo.EstateSettings.HasAccess(client.AgentId))
{
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access",
client.AgentId, client.FirstName, client.LastName, RegionInfo.RegionName);
client.SendAlertMessage("Denied access to private region " + RegionInfo.RegionName + ". You do not have access to this region.");
welcome = false;
}
if(!welcome)
{
try try
{ {
IEventQueue eq = RequestModuleInterface<IEventQueue>(); IEventQueue eq = RequestModuleInterface<IEventQueue>();
@ -1867,50 +1881,52 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[SCENE]: Exception while closing banned client {0} {1}: {2}", client.FirstName, client.LastName, e.Message); m_log.DebugFormat("[SCENE]: Exception while closing unwelcome client {0} {1}: {2}", client.FirstName, client.LastName, e.Message);
}
}
SubscribeToClientEvents(client);
ScenePresence presence;
if (m_restorePresences.ContainsKey(client.AgentId))
{
m_log.DebugFormat("[SCENE]: Restoring agent {0} {1} in {2}", client.Name, client.AgentId, RegionInfo.RegionName);
presence = m_restorePresences[client.AgentId];
m_restorePresences.Remove(client.AgentId);
// This is one of two paths to create avatars that are
// used. This tends to get called more in standalone
// than grid, not really sure why, but as such needs
// an explicity appearance lookup here.
AvatarAppearance appearance = null;
GetAvatarAppearance(client, out appearance);
presence.Appearance = appearance;
presence.initializeScenePresence(client, RegionInfo, this);
m_sceneGraph.AddScenePresence(presence);
lock (m_restorePresences)
{
Monitor.PulseAll(m_restorePresences);
} }
} }
else else
{ {
m_log.DebugFormat( SubscribeToClientEvents(client);
"[SCENE]: Adding new child agent for {0} in {1}", ScenePresence presence;
client.Name, RegionInfo.RegionName);
CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); if (m_restorePresences.ContainsKey(client.AgentId))
{
m_log.DebugFormat("[SCENE]: Restoring agent {0} {1} in {2}", client.Name, client.AgentId, RegionInfo.RegionName);
CreateAndAddScenePresence(client); presence = m_restorePresences[client.AgentId];
m_restorePresences.Remove(client.AgentId);
// This is one of two paths to create avatars that are
// used. This tends to get called more in standalone
// than grid, not really sure why, but as such needs
// an explicity appearance lookup here.
AvatarAppearance appearance = null;
GetAvatarAppearance(client, out appearance);
presence.Appearance = appearance;
presence.initializeScenePresence(client, RegionInfo, this);
m_sceneGraph.AddScenePresence(presence);
lock (m_restorePresences)
{
Monitor.PulseAll(m_restorePresences);
}
}
else
{
m_log.DebugFormat(
"[SCENE]: Adding new child agent for {0} in {1}",
client.Name, RegionInfo.RegionName);
CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
CreateAndAddScenePresence(client);
}
m_LastLogin = Environment.TickCount;
EventManager.TriggerOnNewClient(client);
} }
m_LastLogin = Environment.TickCount;
EventManager.TriggerOnNewClient(client);
} }
protected virtual void SubscribeToClientEvents(IClientAPI client) protected virtual void SubscribeToClientEvents(IClientAPI client)