From 6f644f5322ee0c5ffe6c654387981f1c13f7112d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:19:45 +0100
Subject: implement prim media control permissions serverside in order to stop
bad clients
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 87 ++++++++++++++++------
.../World/Permissions/PermissionsModule.cs | 43 ++++++++++-
.../Region/Framework/Scenes/Scene.Permissions.cs | 21 +++++-
3 files changed, 127 insertions(+), 24 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 378ff4a..d7aede9 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -58,8 +58,21 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
+ ///
+ /// The scene to which this module is attached
+ ///
protected Scene m_scene;
+ ///
+ /// Track the ObjectMedia capabilities given to users
+ ///
+ protected Dictionary m_omCapUsers = new Dictionary();
+
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users
+ ///
+ protected Dictionary m_omuCapUsers = new Dictionary();
+
public void Initialise(IConfigSource config)
{
// TODO: Add config switches to enable/disable this module
@@ -87,16 +100,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
- // We do receive a post to ObjectMedia when a new avatar enters the region - though admittedly this is the
- // avatar that set the texture in the first place.
- // Even though we're registering for POST we're going to get GETS and UPDATES too
- caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaMessage));
+ string omCapUrl = "/CAPS/" + UUID.Random();
+
+ lock (m_omCapUsers)
+ {
+ m_omCapUsers[omCapUrl] = agentID;
+
+ // Even though we're registering for POST we're going to get GETS and UPDATES too
+ caps.RegisterHandler(
+ "ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage));
+ }
+
+ string omuCapUrl = "/CAPS/" + UUID.Random();
- // We do get these posts when the url has been changed.
- // Even though we're registering for POST we're going to get GETS and UPDATES too
- caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
+ lock (m_omuCapUsers)
+ {
+ m_omuCapUsers[omuCapUrl] = agentID;
+
+ // Even though we're registering for POST we're going to get GETS and UPDATES too
+ caps.RegisterHandler(
+ "ObjectMediaNavigate", new RestStreamHandler("POST", omuCapUrl, HandleObjectMediaNavigateMessage));
+ }
}
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
@@ -147,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia path [{0}], raw request [{1}]", path, request);
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
ObjectMediaMessage omm = new ObjectMediaMessage();
@@ -156,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (omm.Request is ObjectMediaRequest)
return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest);
else if (omm.Request is ObjectMediaUpdate)
- return HandleObjectMediaUpdate(omm.Request as ObjectMediaUpdate);
+ return HandleObjectMediaUpdate(path, omm.Request as ObjectMediaUpdate);
throw new Exception(
string.Format(
@@ -165,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
///
- /// Handle a request for media textures
+ /// Handle a fetch request for media textures
///
///
///
@@ -202,9 +226,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
/// Handle an update of media textures.
///
+ /// Path on which this request was made
/// /param>
///
- protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
+ protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu)
{
UUID primId = omu.PrimID;
@@ -216,16 +241,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
"[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
primId, m_scene.RegionInfo.RegionName);
return string.Empty;
- }
+ }
m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
-// for (int i = 0; i < omu.FaceMedia.Length; i++)
-// {
-// MediaEntry me = omu.FaceMedia[i];
-// string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD()));
-// m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v);
-// }
+ for (int i = 0; i < omu.FaceMedia.Length; i++)
+ {
+ MediaEntry me = omu.FaceMedia[i];
+ string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD()));
+ m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v);
+ }
if (omu.FaceMedia.Length > part.GetNumberOfSides())
{
@@ -235,7 +260,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- part.Shape.Media = new List(omu.FaceMedia);
+ List media = part.Shape.Media;
+
+ if (null == media)
+ {
+ part.Shape.Media = new List(omu.FaceMedia);
+ }
+ else
+ {
+ // We need to go through the media textures one at a time to make sure that we have permission
+ // to change them
+ UUID agentId = default(UUID);
+
+ lock (m_omCapUsers)
+ agentId = m_omCapUsers[path];
+
+ for (int i = 0; i < media.Count; i++)
+ {
+ if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
+ media[i] = omu.FaceMedia[i];
+ }
+ }
UpdateMediaUrl(part);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 69b247c..358ea59 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private Dictionary GrantYP = new Dictionary();
private IFriendsModule m_friendsModule;
private IGroupsModule m_groupsModule;
+ private IMoapModule m_moapModule;
#endregion
@@ -248,6 +249,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
+
+ m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.AddCommand(this, "bypass permissions",
"bypass permissions ",
@@ -393,6 +396,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_groupsModule == null)
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
+
+ m_moapModule = m_scene.RequestModuleInterface();
}
public void Close()
@@ -1893,5 +1898,41 @@ namespace OpenSim.Region.CoreModules.World.Permissions
}
return(false);
}
+
+ private bool CanControlPrimMedia(UUID agentID, UUID primID, int face)
+ {
+ if (null == m_moapModule)
+ return false;
+
+ SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
+ if (null == part)
+ return false;
+
+ MediaEntry me = m_moapModule.GetMediaEntry(part, face);
+
+ // If there is no existing media entry then it can be controlled (in this context, created).
+ if (null == me)
+ return true;
+
+ if (IsAdministrator(agentID))
+ return true;
+
+ if ((me.ControlPermissions & MediaPermission.Anyone) == MediaPermission.Anyone)
+ return true;
+
+ if ((me.ControlPermissions & MediaPermission.Owner) == MediaPermission.Owner)
+ {
+ if (agentID == part.OwnerID)
+ return true;
+ }
+
+ if ((me.ControlPermissions & MediaPermission.Group) == MediaPermission.Group)
+ {
+ if (IsGroupMember(part.GroupID, agentID, 0))
+ return true;
+ }
+
+ return false;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 7dab04f..70af978 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -81,6 +81,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene);
+ public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion
public class ScenePermissions
@@ -139,6 +140,7 @@ namespace OpenSim.Region.Framework.Scenes
public event CopyUserInventoryHandler OnCopyUserInventory;
public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport;
+ public event ControlPrimMediaHandler OnControlPrimMedia;
#endregion
#region Object Permission Checks
@@ -947,5 +949,20 @@ namespace OpenSim.Region.Framework.Scenes
}
return true;
}
+
+ public bool CanControlPrimMedia(UUID userID, UUID primID, int face)
+ {
+ ControlPrimMediaHandler handler = OnControlPrimMedia;
+ if (handler != null)
+ {
+ Delegate[] list = handler.GetInvocationList();
+ foreach (ControlPrimMediaHandler h in list)
+ {
+ if (h(userID, primID, face) == false)
+ return false;
+ }
+ }
+ return true;
+ }
}
-}
+}
\ No newline at end of file
--
cgit v1.1