1
0
Эх сурвалжийг харах

partial mantis 8219; on creating or updating items (animationsets, wearables) that reference assets, and user does not have permissions on those, abort and warn, instead of silent invalition of the references to those assets, creating a broken item

UbitUmarov 6 жил өмнө
parent
commit
21b71ff1d8

+ 20 - 2
OpenSim/Framework/AnimationSet.cs

@@ -31,7 +31,8 @@ using OpenMetaverse;
 
 namespace OpenSim.Framework
 {
-    public delegate bool AnimationSetValidator(UUID animID);
+//    public delegate bool AnimationSetValidator(UUID animID);
+    public delegate uint AnimationSetValidator(UUID animID);
 
     public class AnimationSet
     {
@@ -141,7 +142,7 @@ namespace OpenSim.Framework
                 assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key);
             return System.Text.Encoding.ASCII.GetBytes(assetData);
         }
-
+/*
         public bool Validate(AnimationSetValidator val)
         {
             if (m_parseError)
@@ -164,5 +165,22 @@ namespace OpenSim.Framework
 
             return allOk;
         }
+*/
+        public uint Validate(AnimationSetValidator val)
+        {
+            if (m_parseError)
+                return 0;
+
+            uint ret = 0x7fffffff;
+            uint t;
+            foreach (KeyValuePair<string, KeyValuePair<string, UUID>> kvp in m_animations)
+            {
+                t = val(kvp.Value.Value);
+                if (t == 0)
+                    return 0;
+                ret &= t;
+            }
+            return ret;
+        }
     }
 }

+ 70 - 50
OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs

@@ -258,24 +258,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
             {
                 m_uploadState = UploadState.Complete;
 
-                ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
-
+                bool sucess = true;                
                 if (m_createItem)
                 {
-                    CompleteCreateItem(m_createItemCallback);
+                    sucess = CompleteCreateItem(m_createItemCallback);
                 }
                 else if (m_updateItem)
                 {
-                    CompleteItemUpdate(m_updateItemData);
+                    sucess = CompleteItemUpdate(m_updateItemData);
                 }
                 else if (m_updateTaskItem)
                 {
-                    CompleteTaskItemUpdate(m_updateTaskItemData);
+                    sucess = CompleteTaskItemUpdate(m_updateTaskItemData);
                 }
                 else if (m_asset.Local)
                 {
                     m_Scene.AssetService.Store(m_asset);
                 }
+                ourClient.SendAssetUploadCompleteMessage(m_asset.Type, sucess, m_asset.FullID);
             }
 
             m_log.DebugFormat(
@@ -411,46 +411,70 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
         /// Store the asset for the given item when it has been uploaded.
         /// </summary>
         /// <param name="item"></param>
-        private void CompleteItemUpdate(InventoryItemBase item)
+        private bool CompleteItemUpdate(InventoryItemBase item)
         {
 //            m_log.DebugFormat(
 //                "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
 //                m_asset.FullID, item.Name, ourClient.Name);
 
-            ValidateAssets();
-            m_Scene.AssetService.Store(m_asset);
-            if (m_asset.FullID != UUID.Zero)
+            uint perms = ValidateAssets();
+            if(perms == 0)
             {
-                item.AssetID = m_asset.FullID;
-                m_Scene.InventoryService.UpdateItem(item);
+                string error = string.Format("Not enought permissions on asset(s) referenced by item '{0}', update failed", item.Name);
+                ourClient.SendAlertMessage(error);
+                m_transactions.RemoveXferUploader(m_transactionID);
+                ourClient.SendBulkUpdateInventory(item); // invalid the change item on viewer cache
+            }
+            else
+            {
+                m_Scene.AssetService.Store(m_asset);
+                if (m_asset.FullID != UUID.Zero)
+                {
+                    item.AssetID = m_asset.FullID;
+                    m_Scene.InventoryService.UpdateItem(item);
+                }
+                ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);           
+                m_transactions.RemoveXferUploader(m_transactionID);
+                m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
             }
 
-            ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);
-
-            m_transactions.RemoveXferUploader(m_transactionID);
-
-            m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
+            return perms != 0;
         }
 
         /// <summary>
         /// Store the asset for the given task item when it has been uploaded.
         /// </summary>
         /// <param name="taskItem"></param>
-        private void CompleteTaskItemUpdate(TaskInventoryItem taskItem)
+        private bool CompleteTaskItemUpdate(TaskInventoryItem taskItem)
         {
 //            m_log.DebugFormat(
 //                "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
 //                m_asset.FullID, taskItem.Name, ourClient.Name);
 
-            ValidateAssets();
-            m_Scene.AssetService.Store(m_asset);
+            if(ValidateAssets() == 0)
+            {
+                m_transactions.RemoveXferUploader(m_transactionID);
+                string error = string.Format("Not enought permissions on asset(s) referenced by task item '{0}', update failed", taskItem.Name);
+                ourClient.SendAlertMessage(error);
+                // force old asset to viewers ??
+                return false;
+            }
 
+            m_Scene.AssetService.Store(m_asset);
             m_transactions.RemoveXferUploader(m_transactionID);
+            return true;
         }
 
-        private void CompleteCreateItem(uint callbackID)
+        private bool CompleteCreateItem(uint callbackID)
         {
-            ValidateAssets();
+            if(ValidateAssets() == 0)
+            {
+                m_transactions.RemoveXferUploader(m_transactionID);
+                string error = string.Format("Not enought permissions on asset(s) referenced by item '{0}', creation failed", m_name);
+                ourClient.SendAlertMessage(error);
+                return false;
+            }
+
             m_Scene.AssetService.Store(m_asset);
 
             InventoryItemBase item = new InventoryItemBase();
@@ -480,35 +504,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
                 ourClient.SendAlertMessage("Unable to create inventory item");
 
             m_transactions.RemoveXferUploader(m_transactionID);
+            return true;
         }
 
-
-        private void ValidateAssets()
+        private uint ValidateAssets()
         {
+            uint retPerms = 0x7fffffff;
+//            if(m_Scene.Permissions.BypassPermissions())
+//                return retPerms;
+
             if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet)
             {
+
                 AnimationSet animSet = new AnimationSet(m_asset.Data);
 
-                bool allOk = animSet.Validate(x => {
-                    int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
-                    int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
+                retPerms &= animSet.Validate(x => {
+                    const uint required = (uint)(PermissionMask.Transfer | PermissionMask.Copy);
+                    uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
+                    // currrent yes/no rule
                     if ((perms & required) != required)
-                        return false;
-                    return true;
+                        return 0;
+                    return perms;
                     });
 
-                if (!allOk)
-                    m_asset.Data = animSet.ToBytes();
+                return retPerms;
             }
 
             if (m_asset.Type == (sbyte)AssetType.Clothing ||
                 m_asset.Type == (sbyte)AssetType.Bodypart)
             {
+                const uint texturesfullPermMask = (uint)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
                 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
                 string[] lines = content.Split(new char[] {'\n'});
 
-                List<string> validated = new List<string>();
-
+                // on current requiriment of full rigths assume old assets where accepted
                 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
 
                 int textures = 0;
@@ -518,10 +547,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
                     try
                     {
                         if (line.StartsWith("textures "))
-                        {
                             textures = Convert.ToInt32(line.Substring(9));
-                            validated.Add(line);
-                        }
+
                         else if (textures > 0)
                         {
                             string[] parts = line.Split(new char[] {' '});
@@ -532,42 +559,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
                             if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
                                 (allowed.ContainsKey(id) && allowed[id] == tx))
                             {
-                                validated.Add(parts[0] + " " + tx.ToString());
+                                continue;
                             }
                             else
                             {
-                                int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
-                                int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
+                                uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
 
-                                if ((perms & full) != full)
+                                if ((perms & texturesfullPermMask) != texturesfullPermMask)
                                 {
                                     m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
-                                    validated.Add(parts[0] + " " + UUID.Zero.ToString());
+                                    return 0;
                                 }
                                 else
                                 {
-                                    validated.Add(line);
+                                    retPerms &= perms;
                                 }
                             }
                             textures--;
                         }
-                        else
-                        {
-                            validated.Add(line);
-                        }
                     }
                     catch
                     {
                         // If it's malformed, skip it
                     }
                 }
-
-                string final = String.Join("\n", validated.ToArray());
-
-                m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
             }
+            return retPerms;
         }
 
+/* not in use
         /// <summary>
         /// Get the asset data uploaded in this transfer.
         /// </summary>
@@ -582,7 +602,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
 
             return null;
         }
-
+*/
         public void SetOldData(byte[] d)
         {
             m_oldData = d;

+ 9 - 6
OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs

@@ -299,15 +299,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
             else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
             {
                 AnimationSet animSet = new AnimationSet(data);
-                if (!animSet.Validate(x => {
+                uint res = animSet.Validate(x => {
+                        const int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
                         int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x);
-                        int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
+                        // enforce previus perm rule
                         if ((perms & required) != required)
-                            return false;
-                        return true;
-                    }))
+                            return 0;
+                        return (uint) perms;
+                    });
+                if(res == 0)
                 {
-                    data = animSet.ToBytes();
+                    remoteClient.SendAgentAlertMessage("Not enought permissions on asset(s) referenced by animation set '{0}', update failed", false);
+                    return UUID.Zero;
                 }
             }