implement prim media control permissions serverside in order to stop bad clients

prebuild-update
Justin Clark-Casey (justincc) 2010-07-13 23:19:45 +01:00
parent e5615d3a9b
commit 51b208e96c
3 changed files with 127 additions and 24 deletions

View File

@ -58,8 +58,21 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public string Name { get { return "MoapModule"; } } public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } } public Type ReplaceableInterface { get { return null; } }
/// <summary>
/// The scene to which this module is attached
/// </summary>
protected Scene m_scene; protected Scene m_scene;
/// <summary>
/// Track the ObjectMedia capabilities given to users
/// </summary>
protected Dictionary<string, UUID> m_omCapUsers = new Dictionary<string, UUID>();
/// <summary>
/// Track the ObjectMediaUpdate capabilities given to users
/// </summary>
protected Dictionary<string, UUID> m_omuCapUsers = new Dictionary<string, UUID>();
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
// TODO: Add config switches to enable/disable this module // TODO: Add config switches to enable/disable this module
@ -87,16 +100,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat( m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID); "[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 string omCapUrl = "/CAPS/" + UUID.Random();
// 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 lock (m_omCapUsers)
caps.RegisterHandler( {
"ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaMessage)); m_omCapUsers[omCapUrl] = agentID;
// 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 // Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler( caps.RegisterHandler(
"ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage)); "ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage));
}
string omuCapUrl = "/CAPS/" + UUID.Random();
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) public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
@ -147,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected string HandleObjectMediaMessage( protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) 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); OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
ObjectMediaMessage omm = new ObjectMediaMessage(); ObjectMediaMessage omm = new ObjectMediaMessage();
@ -156,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (omm.Request is ObjectMediaRequest) if (omm.Request is ObjectMediaRequest)
return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest); return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest);
else if (omm.Request is ObjectMediaUpdate) else if (omm.Request is ObjectMediaUpdate)
return HandleObjectMediaUpdate(omm.Request as ObjectMediaUpdate); return HandleObjectMediaUpdate(path, omm.Request as ObjectMediaUpdate);
throw new Exception( throw new Exception(
string.Format( string.Format(
@ -165,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
} }
/// <summary> /// <summary>
/// Handle a request for media textures /// Handle a fetch request for media textures
/// </summary> /// </summary>
/// <param name="omr"></param> /// <param name="omr"></param>
/// <returns></returns> /// <returns></returns>
@ -202,9 +226,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
/// <summary> /// <summary>
/// Handle an update of media textures. /// Handle an update of media textures.
/// </summary> /// </summary>
/// <param name="path">Path on which this request was made</param>
/// <param name="omu">/param> /// <param name="omu">/param>
/// <returns></returns> /// <returns></returns>
protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu) protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu)
{ {
UUID primId = omu.PrimID; UUID primId = omu.PrimID;
@ -220,12 +245,12 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId); m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
// for (int i = 0; i < omu.FaceMedia.Length; i++) for (int i = 0; i < omu.FaceMedia.Length; i++)
// { {
// MediaEntry me = omu.FaceMedia[i]; MediaEntry me = omu.FaceMedia[i];
// string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD())); string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD()));
// m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v); m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v);
// } }
if (omu.FaceMedia.Length > part.GetNumberOfSides()) if (omu.FaceMedia.Length > part.GetNumberOfSides())
{ {
@ -235,7 +260,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty; return string.Empty;
} }
List<MediaEntry> media = part.Shape.Media;
if (null == media)
{
part.Shape.Media = new List<MediaEntry>(omu.FaceMedia); part.Shape.Media = new List<MediaEntry>(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); UpdateMediaUrl(part);

View File

@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>();
private IFriendsModule m_friendsModule; private IFriendsModule m_friendsModule;
private IGroupsModule m_groupsModule; private IGroupsModule m_groupsModule;
private IMoapModule m_moapModule;
#endregion #endregion
@ -249,6 +250,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.AddCommand(this, "bypass permissions", m_scene.AddCommand(this, "bypass permissions",
"bypass permissions <true / false>", "bypass permissions <true / false>",
"Bypass permission checks", "Bypass permission checks",
@ -393,6 +396,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_groupsModule == null) if (m_groupsModule == null)
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work"); m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
m_moapModule = m_scene.RequestModuleInterface<IMoapModule>();
} }
public void Close() public void Close()
@ -1893,5 +1898,41 @@ namespace OpenSim.Region.CoreModules.World.Permissions
} }
return(false); 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;
}
} }
} }

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * 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 CopyUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID); public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene); public delegate bool TeleportHandler(UUID userID, Scene scene);
public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion #endregion
public class ScenePermissions public class ScenePermissions
@ -139,6 +140,7 @@ namespace OpenSim.Region.Framework.Scenes
public event CopyUserInventoryHandler OnCopyUserInventory; public event CopyUserInventoryHandler OnCopyUserInventory;
public event DeleteUserInventoryHandler OnDeleteUserInventory; public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport; public event TeleportHandler OnTeleport;
public event ControlPrimMediaHandler OnControlPrimMedia;
#endregion #endregion
#region Object Permission Checks #region Object Permission Checks
@ -947,5 +949,20 @@ namespace OpenSim.Region.Framework.Scenes
} }
return true; 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;
}
} }
} }