aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Agent
diff options
context:
space:
mode:
authorMelanie2010-12-04 07:06:30 +0100
committerMelanie2010-12-04 07:06:30 +0100
commit96446adfa4dd91194c6ce6383927cdece8bdda1f (patch)
treebd0addccfd455ed2e1c2c54f815ae6d6357c72f2 /OpenSim/Region/CoreModules/Agent
parentSimplify updating of agent inventory assets. Make newly created asset IDs (diff)
downloadopensim-SC-96446adfa4dd91194c6ce6383927cdece8bdda1f.zip
opensim-SC-96446adfa4dd91194c6ce6383927cdece8bdda1f.tar.gz
opensim-SC-96446adfa4dd91194c6ce6383927cdece8bdda1f.tar.bz2
opensim-SC-96446adfa4dd91194c6ce6383927cdece8bdda1f.tar.xz
Monitor the UUIDs used to create and update wearable assets. Reject any changed
texture that is not present in the user's inventory full perm. This will prevent "UUID snatching", a copybot-type of attack that can cause clothing makers to be forced to destroy and replace legit items in order to invalidate the copies.
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs10
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs115
2 files changed, 125 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index c66a4ea..85e1c99 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -167,6 +167,16 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
167 { 167 {
168 if (XferUploaders.ContainsKey(transactionID)) 168 if (XferUploaders.ContainsKey(transactionID))
169 { 169 {
170 // Here we need to get the old asset to extract the
171 // texture UUIDs if it's a wearable.
172 if (item.AssetType == (int)AssetType.Bodypart ||
173 item.AssetType == (int)AssetType.Clothing)
174 {
175 AssetBase oldAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
176 if (oldAsset != null)
177 XferUploaders[transactionID].SetOldData(oldAsset.Data);
178 }
179
170 AssetBase asset = GetTransactionAsset(transactionID); 180 AssetBase asset = GetTransactionAsset(transactionID);
171 181
172 if (asset != null) 182 if (asset != null)
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index a7929ba..b8c8c85 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Reflection; 30using System.Reflection;
31using System.Collections.Generic;
31using log4net; 32using log4net;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
@@ -38,6 +39,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
38{ 39{
39 public class AssetXferUploader 40 public class AssetXferUploader
40 { 41 {
42 // Viewer's notion of the default texture
43 private UUID defaultID = new UUID("5748decc-f629-461c-9a36-a35a221fe21f");
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 45
43 private AssetBase m_asset; 46 private AssetBase m_asset;
@@ -55,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
55 private UUID TransactionID = UUID.Zero; 58 private UUID TransactionID = UUID.Zero;
56 private sbyte type = 0; 59 private sbyte type = 0;
57 private byte wearableType = 0; 60 private byte wearableType = 0;
61 private byte[] m_oldData = null;
58 public ulong XferID; 62 public ulong XferID;
59 private Scene m_Scene; 63 private Scene m_Scene;
60 64
@@ -219,6 +223,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
219 223
220 private void DoCreateItem(uint callbackID) 224 private void DoCreateItem(uint callbackID)
221 { 225 {
226 ValidateAssets();
222 m_Scene.AssetService.Store(m_asset); 227 m_Scene.AssetService.Store(m_asset);
223 228
224 InventoryItemBase item = new InventoryItemBase(); 229 InventoryItemBase item = new InventoryItemBase();
@@ -245,6 +250,71 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
245 ourClient.SendAlertMessage("Unable to create inventory item"); 250 ourClient.SendAlertMessage("Unable to create inventory item");
246 } 251 }
247 252
253 private void ValidateAssets()
254 {
255 if (m_asset.Type == (sbyte)AssetType.Clothing ||
256 m_asset.Type == (sbyte)AssetType.Bodypart)
257 {
258 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
259 string[] lines = content.Split(new char[] {'\n'});
260
261 List<string> validated = new List<string>();
262
263 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
264
265 int textures = 0;
266
267 foreach (string line in lines)
268 {
269 try
270 {
271 if (line.StartsWith("textures "))
272 {
273 textures = Convert.ToInt32(line.Substring(9));
274 validated.Add(line);
275 }
276 else if (textures > 0)
277 {
278 string[] parts = line.Split(new char[] {' '});
279
280 UUID tx = new UUID(parts[1]);
281 int id = Convert.ToInt32(parts[0]);
282
283 if (tx == defaultID || tx == UUID.Zero ||
284 (allowed.ContainsKey(id) && allowed[id] == tx))
285 {
286 validated.Add(parts[0] + " " + tx.ToString());
287 }
288 else
289 {
290 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
291 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
292
293 if ((perms & full) != full)
294 {
295 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
296 validated.Add(parts[0] + " " + defaultID.ToString());
297 }
298 }
299 textures--;
300 }
301 else
302 {
303 validated.Add(line);
304 }
305 }
306 catch
307 {
308 // If it's malformed, skip it
309 }
310 }
311
312 string final = String.Join("\n", validated.ToArray());
313
314 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
315 }
316 }
317
248 /// <summary> 318 /// <summary>
249 /// Get the asset data uploaded in this transfer. 319 /// Get the asset data uploaded in this transfer.
250 /// </summary> 320 /// </summary>
@@ -253,10 +323,55 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
253 { 323 {
254 if (m_finished) 324 if (m_finished)
255 { 325 {
326 ValidateAssets();
256 return m_asset; 327 return m_asset;
257 } 328 }
258 329
259 return null; 330 return null;
260 } 331 }
332
333 public void SetOldData(byte[] d)
334 {
335 m_oldData = d;
336 }
337
338 private Dictionary<int,UUID> ExtractTexturesFromOldData()
339 {
340 Dictionary<int,UUID> result = new Dictionary<int,UUID>();
341 if (m_oldData == null)
342 return result;
343
344 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
345 string[] lines = content.Split(new char[] {'\n'});
346
347 int textures = 0;
348
349 foreach (string line in lines)
350 {
351 try
352 {
353 if (line.StartsWith("textures "))
354 {
355 textures = Convert.ToInt32(line.Substring(9));
356 }
357 else if (textures > 0)
358 {
359 string[] parts = line.Split(new char[] {' '});
360
361 UUID tx = new UUID(parts[1]);
362 int id = Convert.ToInt32(parts[0]);
363 result[id] = tx;
364 textures--;
365 }
366 }
367 catch
368 {
369 // If it's malformed, skip it
370 }
371 }
372
373 return result;
374 }
261 } 375 }
262} 376}
377