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
parent
324bda8ab9
commit
21b71ff1d8
|
@ -31,7 +31,8 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public delegate bool AnimationSetValidator(UUID animID);
|
// public delegate bool AnimationSetValidator(UUID animID);
|
||||||
|
public delegate uint AnimationSetValidator(UUID animID);
|
||||||
|
|
||||||
public class AnimationSet
|
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);
|
assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key);
|
||||||
return System.Text.Encoding.ASCII.GetBytes(assetData);
|
return System.Text.Encoding.ASCII.GetBytes(assetData);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
public bool Validate(AnimationSetValidator val)
|
public bool Validate(AnimationSetValidator val)
|
||||||
{
|
{
|
||||||
if (m_parseError)
|
if (m_parseError)
|
||||||
|
@ -164,5 +165,22 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
return allOk;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,24 +258,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
{
|
{
|
||||||
m_uploadState = UploadState.Complete;
|
m_uploadState = UploadState.Complete;
|
||||||
|
|
||||||
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
|
bool sucess = true;
|
||||||
|
|
||||||
if (m_createItem)
|
if (m_createItem)
|
||||||
{
|
{
|
||||||
CompleteCreateItem(m_createItemCallback);
|
sucess = CompleteCreateItem(m_createItemCallback);
|
||||||
}
|
}
|
||||||
else if (m_updateItem)
|
else if (m_updateItem)
|
||||||
{
|
{
|
||||||
CompleteItemUpdate(m_updateItemData);
|
sucess = CompleteItemUpdate(m_updateItemData);
|
||||||
}
|
}
|
||||||
else if (m_updateTaskItem)
|
else if (m_updateTaskItem)
|
||||||
{
|
{
|
||||||
CompleteTaskItemUpdate(m_updateTaskItemData);
|
sucess = CompleteTaskItemUpdate(m_updateTaskItemData);
|
||||||
}
|
}
|
||||||
else if (m_asset.Local)
|
else if (m_asset.Local)
|
||||||
{
|
{
|
||||||
m_Scene.AssetService.Store(m_asset);
|
m_Scene.AssetService.Store(m_asset);
|
||||||
}
|
}
|
||||||
|
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, sucess, m_asset.FullID);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat(
|
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.
|
/// Store the asset for the given item when it has been uploaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item"></param>
|
/// <param name="item"></param>
|
||||||
private void CompleteItemUpdate(InventoryItemBase item)
|
private bool CompleteItemUpdate(InventoryItemBase item)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
|
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
|
||||||
// m_asset.FullID, item.Name, ourClient.Name);
|
// m_asset.FullID, item.Name, ourClient.Name);
|
||||||
|
|
||||||
ValidateAssets();
|
uint perms = ValidateAssets();
|
||||||
m_Scene.AssetService.Store(m_asset);
|
if(perms == 0)
|
||||||
if (m_asset.FullID != UUID.Zero)
|
|
||||||
{
|
{
|
||||||
item.AssetID = m_asset.FullID;
|
string error = string.Format("Not enought permissions on asset(s) referenced by item '{0}', update failed", item.Name);
|
||||||
m_Scene.InventoryService.UpdateItem(item);
|
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);
|
return perms != 0;
|
||||||
|
|
||||||
m_transactions.RemoveXferUploader(m_transactionID);
|
|
||||||
|
|
||||||
m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Store the asset for the given task item when it has been uploaded.
|
/// Store the asset for the given task item when it has been uploaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="taskItem"></param>
|
/// <param name="taskItem"></param>
|
||||||
private void CompleteTaskItemUpdate(TaskInventoryItem taskItem)
|
private bool CompleteTaskItemUpdate(TaskInventoryItem taskItem)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
|
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
|
||||||
// m_asset.FullID, taskItem.Name, ourClient.Name);
|
// m_asset.FullID, taskItem.Name, ourClient.Name);
|
||||||
|
|
||||||
ValidateAssets();
|
if(ValidateAssets() == 0)
|
||||||
m_Scene.AssetService.Store(m_asset);
|
{
|
||||||
|
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);
|
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);
|
m_Scene.AssetService.Store(m_asset);
|
||||||
|
|
||||||
InventoryItemBase item = new InventoryItemBase();
|
InventoryItemBase item = new InventoryItemBase();
|
||||||
|
@ -480,35 +504,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
ourClient.SendAlertMessage("Unable to create inventory item");
|
ourClient.SendAlertMessage("Unable to create inventory item");
|
||||||
|
|
||||||
m_transactions.RemoveXferUploader(m_transactionID);
|
m_transactions.RemoveXferUploader(m_transactionID);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private uint ValidateAssets()
|
||||||
private void ValidateAssets()
|
|
||||||
{
|
{
|
||||||
|
uint retPerms = 0x7fffffff;
|
||||||
|
// if(m_Scene.Permissions.BypassPermissions())
|
||||||
|
// return retPerms;
|
||||||
|
|
||||||
if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet)
|
if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet)
|
||||||
{
|
{
|
||||||
|
|
||||||
AnimationSet animSet = new AnimationSet(m_asset.Data);
|
AnimationSet animSet = new AnimationSet(m_asset.Data);
|
||||||
|
|
||||||
bool allOk = animSet.Validate(x => {
|
retPerms &= animSet.Validate(x => {
|
||||||
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
|
const uint required = (uint)(PermissionMask.Transfer | PermissionMask.Copy);
|
||||||
int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
|
uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
|
||||||
|
// currrent yes/no rule
|
||||||
if ((perms & required) != required)
|
if ((perms & required) != required)
|
||||||
return false;
|
return 0;
|
||||||
return true;
|
return perms;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!allOk)
|
return retPerms;
|
||||||
m_asset.Data = animSet.ToBytes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_asset.Type == (sbyte)AssetType.Clothing ||
|
if (m_asset.Type == (sbyte)AssetType.Clothing ||
|
||||||
m_asset.Type == (sbyte)AssetType.Bodypart)
|
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 content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
|
||||||
string[] lines = content.Split(new char[] {'\n'});
|
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();
|
Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
|
||||||
|
|
||||||
int textures = 0;
|
int textures = 0;
|
||||||
|
@ -518,10 +547,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (line.StartsWith("textures "))
|
if (line.StartsWith("textures "))
|
||||||
{
|
|
||||||
textures = Convert.ToInt32(line.Substring(9));
|
textures = Convert.ToInt32(line.Substring(9));
|
||||||
validated.Add(line);
|
|
||||||
}
|
|
||||||
else if (textures > 0)
|
else if (textures > 0)
|
||||||
{
|
{
|
||||||
string[] parts = line.Split(new char[] {' '});
|
string[] parts = line.Split(new char[] {' '});
|
||||||
|
@ -532,42 +559,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
|
if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
|
||||||
(allowed.ContainsKey(id) && allowed[id] == tx))
|
(allowed.ContainsKey(id) && allowed[id] == tx))
|
||||||
{
|
{
|
||||||
validated.Add(parts[0] + " " + tx.ToString());
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
|
uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
|
||||||
int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
|
|
||||||
|
|
||||||
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
validated.Add(line);
|
retPerms &= perms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
textures--;
|
textures--;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
validated.Add(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// If it's malformed, skip it
|
// 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>
|
/// <summary>
|
||||||
/// Get the asset data uploaded in this transfer.
|
/// Get the asset data uploaded in this transfer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -582,7 +602,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public void SetOldData(byte[] d)
|
public void SetOldData(byte[] d)
|
||||||
{
|
{
|
||||||
m_oldData = d;
|
m_oldData = d;
|
||||||
|
|
|
@ -299,15 +299,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
|
else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
|
||||||
{
|
{
|
||||||
AnimationSet animSet = new AnimationSet(data);
|
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 perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x);
|
||||||
int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
|
// enforce previus perm rule
|
||||||
if ((perms & required) != required)
|
if ((perms & required) != required)
|
||||||
return false;
|
return 0;
|
||||||
return true;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue