From 2805ec64662494d680925c6034e59b823e051a9d Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 31 Dec 2012 23:04:28 -0500 Subject: * Fixed a bug that replayed old cached appearance when changing outfits * Added suser(bad client) DOS protection by limiting the max cacheitems to the maximum sane amount. * Prevents potential numerous loops from running amok and index errors if the client purposely provides bad cache info. * If the XBakes service wasn't running, the SetAvatarAppearance routine would crash when contacting the XBakes service even though it was in a Try/Catch for the appropriate error type. It only properly error handles with the type Exception :(. (commented on that because it's unusual) --- .../Linden/Caps/UploadBakedTextureModule.cs | 123 ++++++++++++++------- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 34 +++++- 2 files changed, 111 insertions(+), 46 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 6778ba5..6bed95f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -119,13 +119,20 @@ namespace OpenSim.Region.ClientStack.Linden private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { + int maxCacheitemsLoop = cacheItems.Length; + if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES) + { + maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; + m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); + } + m_BakedTextureModule = m_scene.RequestModuleInterface(); if (cacheItems.Length > 0) { - m_log.Info("[Cacheitems]: " + cacheItems.Length); - for (int iter = 0; iter < cacheItems.Length; iter++) + m_log.Debug("[Cacheitems]: " + cacheItems.Length); + for (int iter = 0; iter < maxCacheitemsLoop; iter++) { - m_log.Info("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + cacheItems[iter].TextureID); } @@ -133,65 +140,99 @@ namespace OpenSim.Region.ClientStack.Linden if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) { - WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; - if (existingitems == null) + WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; + if (existingitems == null) + { + if (m_BakedTextureModule != null) { - if (m_BakedTextureModule != null) + WearableCacheItem[] savedcache = null; + try { - WearableCacheItem[] savedcache = null; - try - { - if (p.Appearance.WearableCacheItemsDirty) - { - savedcache = m_BakedTextureModule.Get(p.UUID); - p.Appearance.WearableCacheItems = savedcache; - p.Appearance.WearableCacheItemsDirty = false; - } - - } - catch (InvalidOperationException) + if (p.Appearance.WearableCacheItemsDirty) { + savedcache = m_BakedTextureModule.Get(p.UUID); + p.Appearance.WearableCacheItems = savedcache; + p.Appearance.WearableCacheItemsDirty = false; } - if (savedcache != null) - existingitems = savedcache; } + /* + * The following Catch types DO NOT WORK with m_BakedTextureModule.Get + * it jumps to the General Packet Exception Handler if you don't catch Exception! + * + catch (System.Net.Sockets.SocketException) + { + cacheItems = null; + } + catch (WebException) + { + cacheItems = null; + } + catch (InvalidOperationException) + { + cacheItems = null; + } */ + catch (Exception) + { + // The service logs a sufficient error message. + } + + + if (savedcache != null) + existingitems = savedcache; } - // Existing items null means it's a fully new appearance - if (existingitems == null) - { + } + // Existing items null means it's a fully new appearance + if (existingitems == null) + { - for (int iter = 0; iter < cacheItems.Length; iter++) + for (int i = 0; i < maxCacheitemsLoop; i++) + { + if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { - - cacheItems[iter].TextureID = textureEntry.FaceTextures[cacheItems[iter].TextureIndex].TextureID; + cacheItems[i].TextureID = + textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; if (m_scene.AssetService != null) - cacheItems[iter].TextureAsset = m_scene.AssetService.GetCached(cacheItems[iter].TextureID.ToString()); - - + cacheItems[i].TextureAsset = + m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); + } + else + { + m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } + + } - else - - + } + else + + + { + // for each uploaded baked texture + for (int i = 0; i < maxCacheitemsLoop; i++) { - // for each uploaded baked texture - for (int i = 0; i < cacheItems.Length; i++) + if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { cacheItems[i].TextureID = textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; } - - for (int i = 0; i < cacheItems.Length; i++) + else { - if (cacheItems[i].TextureAsset == null) - { - cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); - } + m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } } - + for (int i = 0; i < maxCacheitemsLoop; i++) + { + if (cacheItems[i].TextureAsset == null) + { + cacheItems[i].TextureAsset = + m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); + } + } + } + + p.Appearance.WearableCacheItems = cacheItems; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9e39699..d46adb8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11727,6 +11727,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP IAssetService cache = m_scene.AssetService; IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); + //bakedTextureModule = null; + int maxWearablesLoop = cachedtex.WearableData.Length; + if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) + maxWearablesLoop = AvatarWearable.MAX_WEARABLES; + if (bakedTextureModule != null && cache != null) { // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid @@ -11742,10 +11747,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP p.Appearance.WearableCacheItems = cacheItems; p.Appearance.WearableCacheItemsDirty = false; } + + /* + * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! + * + catch (System.Net.Sockets.SocketException) + { + cacheItems = null; + } + catch (WebException) + { + cacheItems = null; + } catch (InvalidOperationException) { cacheItems = null; + } */ + catch (Exception) + { + cacheItems = null; } + } else if (p.Appearance.WearableCacheItems != null) { @@ -11766,10 +11788,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + if (cacheItems != null) { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { WearableCacheItem item = WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); @@ -11777,8 +11800,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].HostName = new byte[0]; - if (item != null) + if (item != null && cachedtex.WearableData[i].ID == item.CacheId) { + cachedresp.WearableData[i].TextureID = item.TextureID; } else @@ -11789,7 +11813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; @@ -11803,7 +11827,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (cache == null) { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; @@ -11814,7 +11838,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; -- cgit v1.1