diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index c48ede5f80..a369a754dd 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -13,7 +13,7 @@ people that make the day to day of OpenSim happen. * lbsa71 (Tribal Media AB) * Sean Dague / sdague (IBM) * Tedd -* justincc (Black Dress Technology) +* justincc * Teravus (w3z) * Johan Berntsson (3Di) * Ckrinke (Charles Krinke) @@ -29,6 +29,7 @@ people that make the day to day of OpenSim happen. * nlin (3Di) * Arthur Rodrigo S Valadares (IBM) + = Past Open Sim Developers = These folks are alumns of the OpenSim core group, but are now currently not active. Their great contributions helped get us to @@ -44,6 +45,7 @@ where we are today. * Darok * Alondria + = Additional OpenSim Contributors = These folks have contributed code patches to OpenSim to help make it what it is today. @@ -90,6 +92,7 @@ what it is today. * maimedleech * Mic Bowman * Michelle Argus +* Michael Cortez (The Flotsam Project, http://osflotsam.org/) * Mike Osias (IBM) * Mike Pitman (IBM) * mikkopa/_someone - RealXtend @@ -123,8 +126,7 @@ what it is today. * Zha Ewry - -LSL Devs += LSL Devs = * Alondria * CharlieO @@ -132,7 +134,7 @@ LSL Devs * Melanie Thielker -Testers += Testers = * Ai Austin * CharlieO (LSL) @@ -140,10 +142,6 @@ Testers * openlifegrid.com -AssetInventory Server and some plugins are based on Cable Beach -Cable Beach is Copyright (c) 2008 Intel Corporation -see http://forge.opensimulator.org/gf/project/assetserver/ - This software uses components from the following developers: * Sleepycat Software (Berkeley DB) * SQLite (Public Domain) @@ -161,6 +159,10 @@ This software uses components from the following developers: * log4net (http://logging.apache.org/log4net/) * GlynnTucker.Cache (http://gtcache.sourceforge.net/) +Some plugins are based on Cable Beach +Cable Beach is Copyright (c) 2008 Intel Corporation +see http://forge.opensimulator.org/gf/project/assetserver/ + In addition, we would like to thank: * The Mono Project * The NANT Developers diff --git a/OpenSim/Client/Linden/LLStandaloneLoginService.cs b/OpenSim/Client/Linden/LLStandaloneLoginService.cs index 2a13502145..122110d406 100644 --- a/OpenSim/Client/Linden/LLStandaloneLoginService.cs +++ b/OpenSim/Client/Linden/LLStandaloneLoginService.cs @@ -139,15 +139,8 @@ namespace OpenSim.Client.Linden return m_regionsConnector.RequestNeighbourInfo(homeRegionId); } - /// - /// Prepare a login to the given region. This involves both telling the region to expect a connection - /// and appropriately customising the response to the user. - /// - /// - /// - /// - /// true if the region was successfully contacted, false otherwise - protected override bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient) + protected override bool PrepareLoginToRegion( + RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient) { IPEndPoint endPoint = regionInfo.ExternalEndPoint; response.SimAddress = endPoint.Address.ToString(); @@ -204,7 +197,8 @@ namespace OpenSim.Client.Linden agent.Appearance = m_userManager.GetUserAppearance(user.ID); if (agent.Appearance == null) { - m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname); + m_log.WarnFormat( + "[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname); agent.Appearance = new AvatarAppearance(agent.AgentID); } @@ -243,7 +237,8 @@ namespace OpenSim.Client.Linden return; } - m_regionsConnector.LogOffUserFromGrid(SimInfo.RegionHandle, theUser.ID, theUser.CurrentAgent.SecureSessionID, "Logging you off"); + m_regionsConnector.LogOffUserFromGrid( + SimInfo.RegionHandle, theUser.ID, theUser.CurrentAgent.SecureSessionID, "Logging you off"); } } } diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index df29c4edc7..c5560b84cc 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -57,8 +57,8 @@ namespace OpenSim.Framework.Capabilities public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, bool isScriptRunning, byte[] data); - public delegate List FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, - bool fetchFolders, bool fetchItems, int sortOrder); + public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder, out int version); /// /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that @@ -89,7 +89,7 @@ namespace OpenSim.Framework.Capabilities //private static readonly string m_requestTexture = "0003/"; private static readonly string m_notecardUpdatePath = "0004/"; private static readonly string m_notecardTaskUpdatePath = "0005/"; - // private static readonly string m_fetchInventoryPath = "0006/"; + private static readonly string m_fetchInventoryPath = "0006/"; // The following entries are in a module, however, they are also here so that we don't re-assign // the path to another cap by mistake. @@ -207,7 +207,7 @@ namespace OpenSim.Framework.Capabilities // As of RC 1.22.9 of the Linden client this is // supported - // m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); + m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires @@ -449,57 +449,58 @@ namespace OpenSim.Framework.Capabilities contents.owner_id = invFetch.owner_id; contents.folder_id = invFetch.folder_id; - // The version number being sent back was originally 1. - // Unfortunately, on 1.19.1.4, this means that we see a problem where on subsequent logins - // without clearing client cache, objects in the root folder disappear until the cache is cleared, - // at which point they reappear. - // - // Seeing the version to something other than 0 may be the right thing to do, but there is - // a greater subtlety of the second life protocol that needs to be understood first. - contents.version = 0; - - contents.descendents = 0; reply.folders.Array.Add(contents); - List itemList = null; + InventoryCollection inv = new InventoryCollection(); + inv.Folders = new List(); + inv.Items = new List(); + int version = 0; if (CAPSFetchInventoryDescendents != null) { - itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order); + inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); } - if (itemList != null) + if (inv.Folders != null) { - foreach (InventoryItemBase invItem in itemList) + foreach (InventoryFolderBase invFolder in inv.Folders) + { + contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); + } + } + + if (inv.Items != null) + { + foreach (InventoryItemBase invItem in inv.Items) { contents.items.Array.Add(ConvertInventoryItem(invItem)); } } - /* The following block is removed as it ALWAYS sends the error to the client because the RC 1.22.9 client tries to - find items that have become dissasociated with a paret folder and have parent of 00000000-0000-00000.... - else - { - IClientAPI client = GetClient(m_agentID); - // We're going to both notify the client of inventory service failure and send back a 'no folder contents' response. - // If we don't send back the response, - // the client becomes unhappy (see Teravus' comment in FetchInventoryRequest()) - if (client != null) - { - client.SendAgentAlertMessage( - "AGIN0001E: The inventory service has either failed or is not responding. Your inventory will not function properly for the rest of this session. Please clear your cache and relog.", - true); - } - else - { - m_log.ErrorFormat( - "[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure", - m_agentID); - } - }*/ + contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; + contents.version = version; - contents.descendents = contents.items.Array.Count; return reply; } + /// + /// Convert an internal inventory folder object into an LLSD object. + /// + /// + /// + private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) + { + LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); + llsdFolder.folder_id = invFolder.ID; + llsdFolder.parent_id = invFolder.ParentID; + llsdFolder.name = invFolder.Name; + if (invFolder.Type == -1) + llsdFolder.type = "-1"; + else + llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; + llsdFolder.preferred_type = "-1"; + + return llsdFolder; + } + /// /// Convert an internal inventory item object into an LLSD object. /// @@ -529,15 +530,29 @@ namespace OpenSim.Framework.Capabilities llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; - llsdItem.permissions.group_id = UUID.Zero; - llsdItem.permissions.group_mask = 0; - llsdItem.permissions.is_owner_group = false; + llsdItem.permissions.group_id = invItem.GroupID; + llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; + llsdItem.permissions.is_owner_group = invItem.GroupOwned; llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; - llsdItem.permissions.owner_id = m_agentID; // FixMe + llsdItem.permissions.owner_id = m_agentID; llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; llsdItem.sale_info = new LLSDSaleInfo(); - llsdItem.sale_info.sale_price = 10; - llsdItem.sale_info.sale_type = "not"; + llsdItem.sale_info.sale_price = invItem.SalePrice; + switch (invItem.SaleType) + { + default: + llsdItem.sale_info.sale_type = "not"; + break; + case 1: + llsdItem.sale_info.sale_type = "original"; + break; + case 2: + llsdItem.sale_info.sale_type = "copy"; + break; + case 3: + llsdItem.sale_info.sale_type = "contents"; + break; + } return llsdItem; } diff --git a/OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs new file mode 100644 index 0000000000..3c216e9c15 --- /dev/null +++ b/OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; + +namespace OpenSim.Framework.Capabilities +{ + [OSDMap] + public class LLSDInventoryFolder + { + public UUID folder_id; + public UUID parent_id; + public string name; + public string type; + public string preferred_type; + } +} diff --git a/OpenSim/Framework/Capabilities/LLSDInventoryItem.cs b/OpenSim/Framework/Capabilities/LLSDInventoryItem.cs index d0498f63cc..cce18d7498 100644 --- a/OpenSim/Framework/Capabilities/LLSDInventoryItem.cs +++ b/OpenSim/Framework/Capabilities/LLSDInventoryItem.cs @@ -90,6 +90,7 @@ namespace OpenSim.Framework.Capabilities public UUID agent_id; public int descendents; public UUID folder_id; + public OSDArray categories = new OSDArray(); public OSDArray items = new OSDArray(); public UUID owner_id; public int version; diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index cac6616932..bf59f8e43e 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs @@ -1063,7 +1063,18 @@ namespace OpenSim.Framework.Communications.Services protected abstract RegionInfo RequestClosestRegion(string region); protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle); protected abstract RegionInfo GetRegionInfo(UUID homeRegionId); - protected abstract bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint client); + + /// + /// Prepare a login to the given region. This involves both telling the region to expect a connection + /// and appropriately customising the response to the user. + /// + /// + /// + /// + /// + /// true if the region was successfully contacted, false otherwise + protected abstract bool PrepareLoginToRegion( + RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint client); /// /// Add active gestures of the user to the login response. diff --git a/OpenSim/Framework/InventoryFolderBase.cs b/OpenSim/Framework/InventoryFolderBase.cs index 1869d48f90..0edb2c6103 100644 --- a/OpenSim/Framework/InventoryFolderBase.cs +++ b/OpenSim/Framework/InventoryFolderBase.cs @@ -30,7 +30,7 @@ using OpenMetaverse; namespace OpenSim.Framework { /// - /// A Class for folders which contain users inventory + /// User inventory folder /// public class InventoryFolderBase : InventoryNodeBase { diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs index 2ef4a36855..3f72c31af2 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs @@ -94,6 +94,7 @@ namespace OpenSim.Framework.Servers.HttpServer Stream requestStream = request.GetRequestStream(); requestStream.Write(buffer.ToArray(), 0, length); + requestStream.Close(); TResponse deserial = default(TResponse); using (WebResponse resp = request.GetResponse()) { @@ -101,7 +102,6 @@ namespace OpenSim.Framework.Servers.HttpServer deserial = (TResponse)deserializer.Deserialize(resp.GetResponseStream()); resp.Close(); } - requestStream.Close(); return deserial; } } diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 0d3cc23974..937f76bb72 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; +using System.Threading; using log4net; using Nini.Config; using OpenMetaverse; @@ -38,9 +39,12 @@ using OpenMetaverse.Imaging; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Agent.TextureSender { + public delegate void J2KDecodeDelegate(UUID AssetId); + public class J2KDecoderModule : IRegionModule, IJ2KDecoder { #region IRegionModule Members @@ -53,8 +57,12 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender /// private readonly Dictionary m_cacheddecode = new Dictionary(); private bool OpenJpegFail = false; - private readonly string CacheFolder = Util.dataDir() + "/j2kDecodeCache"; - private readonly J2KDecodeFileCache fCache; + private string CacheFolder = Util.dataDir() + "/j2kDecodeCache"; + private int CacheTimeout = 720; + private J2KDecodeFileCache fCache = null; + private Thread CleanerThread = null; + private IAssetService AssetService = null; + private Scene m_Scene = null; /// /// List of client methods to notify of results of decode @@ -63,17 +71,37 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender public J2KDecoderModule() { - fCache = new J2KDecodeFileCache(CacheFolder); } public void Initialise(Scene scene, IConfigSource source) { + if (m_Scene == null) + m_Scene = scene; + + IConfig j2kConfig = source.Configs["J2KDecoder"]; + if (j2kConfig != null) + { + CacheFolder = j2kConfig.GetString("CacheDir", CacheFolder); + CacheTimeout = j2kConfig.GetInt("CacheTimeout", CacheTimeout); + } + + if (fCache == null) + fCache = new J2KDecodeFileCache(CacheFolder, CacheTimeout); + scene.RegisterModuleInterface(this); + + if (CleanerThread == null && CacheTimeout != 0) + { + CleanerThread = new Thread(CleanCache); + CleanerThread.Name = "J2KCleanerThread"; + CleanerThread.IsBackground = true; + CleanerThread.Start(); + } } public void PostInitialise() { - + AssetService = m_Scene.AssetService; } public void Close() @@ -329,8 +357,9 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender // Cache Decoded layers lock (m_cacheddecode) { - if (!m_cacheddecode.ContainsKey(AssetId)) - m_cacheddecode.Add(AssetId, layers); + if (m_cacheddecode.ContainsKey(AssetId)) + m_cacheddecode.Remove(AssetId); + m_cacheddecode.Add(AssetId, layers); } @@ -348,11 +377,34 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender } } } + + private void CleanCache() + { + m_log.Info("[J2KDecoderModule]: Cleaner thread started"); + + while (true) + { + if (AssetService != null) + fCache.ScanCacheFiles(RedecodeTexture); + + System.Threading.Thread.Sleep(600000); + } + } + + private void RedecodeTexture(UUID assetID) + { + AssetBase texture = AssetService.Get(assetID.ToString()); + if (texture == null) + return; + + doJ2kDecode(assetID, texture.Data); + } } public class J2KDecodeFileCache { private readonly string m_cacheDecodeFolder; + private readonly int m_cacheTimeout; private bool enabled = true; private static readonly ILog m_log @@ -362,9 +414,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender /// Creates a new instance of a file cache /// /// base folder for the cache. Will be created if it doesn't exist - public J2KDecodeFileCache(string pFolder) + public J2KDecodeFileCache(string pFolder, int timeout) { m_cacheDecodeFolder = pFolder; + m_cacheTimeout = timeout; if (!Directory.Exists(pFolder)) { Createj2KCacheFolder(pFolder); @@ -555,6 +608,16 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender return String.Format("j2kCache_{0}.cache", AssetId); } + public UUID AssetIdFromFileName(string fileName) + { + string rawId = fileName.Replace("j2kCache_", "").Replace(".cache", ""); + UUID asset; + if (!UUID.TryParse(rawId, out asset)) + return UUID.Zero; + + return asset; + } + /// /// Creates the Cache Folder /// @@ -619,5 +682,23 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender enabled = false; } } + + public void ScanCacheFiles(J2KDecodeDelegate decode) + { + DirectoryInfo dir = new DirectoryInfo(m_cacheDecodeFolder); + FileInfo[] files = dir.GetFiles("j2kCache_*.cache"); + + foreach (FileInfo f in files) + { + TimeSpan fileAge = DateTime.Now - f.CreationTime; + + if (m_cacheTimeout != 0 && fileAge >= TimeSpan.FromMinutes(m_cacheTimeout)) + { + File.Delete(f.Name); + decode(AssetIdFromFileName(f.Name)); + System.Threading.Thread.Sleep(5000); + } + } + } } } diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index c91b63eec2..53b8ebc185 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -1,29 +1,29 @@ /* -Copyright (c) Contributors, http://osflotsam.org/ -See CONTRIBUTORS.TXT for a full list of copyright holders. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Flotsam Project nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ // Uncomment to make asset Get requests for existing // #define WAIT_ON_INPROGRESS_REQUESTS diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index d51ed400ea..1696d82587 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -45,6 +45,7 @@ using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Setup; @@ -102,18 +103,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Monitor.Wait(this, 60000); } - /* - cm.UserAdminService.AddUser(userFirstName, userLastName, string.Empty, string.Empty, 1000, 1000, userId); - CachedUserInfo userInfo = cm.UserProfileCacheService.GetUserDetails(userId, InventoryReceived); - userInfo.FetchInventory(); - for (int i = 0 ; i < 50 ; i++) - { - if (userInfo.HasReceivedInventory == true) - break; - Thread.Sleep(200); - } - Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)"); - */ + Console.WriteLine("here"); // Create asset SceneObjectGroup object1; @@ -148,7 +138,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; //userInfo.RootFolder.FindFolderByPath("Objects").ID; - InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object); + //InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object); + Console.WriteLine("here2"); + IInventoryService inventoryService = scene.InventoryService; + InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); + InventoryCollection rootContents = inventoryService.GetFolderContent(userId, rootFolder.ID); + InventoryFolderBase objsFolder = null; + foreach (InventoryFolderBase folder in rootContents.Folders) + if (folder.Name == "Objects") + objsFolder = folder; item1.Folder = objsFolder.ID; scene.AddInventoryItem(userId, item1); diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index e577fbe951..e83b1a8913 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -484,6 +484,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender GetParams(partsDelimiter, ref nextLine, 11, ref points); graph.FillPolygon(myBrush, points); } + else if (nextLine.StartsWith("Polygon")) + { + PointF[] points = null; + GetParams(partsDelimiter, ref nextLine, 7, ref points); + graph.DrawPolygon(drawPen, points); + } else if (nextLine.StartsWith("Ellipse")) { float x = 0; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index c8f04a5cbf..3c3534f5dc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -88,13 +88,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory } // If not, go get them and place them in the cache - Dictionary folders = m_Connector.GetSystemFolders(presence.UUID); + Dictionary folders = CacheSystemFolders(presence.UUID); m_log.DebugFormat("[INVENTORY CACHE]: OnMakeRootAgent in {0}, fetched system folders for {1} {2}: count {3}", presence.Scene.RegionInfo.RegionName, presence.Firstname, presence.Lastname, folders.Count); - - if (folders.Count > 0) - lock (m_InventoryCache) - m_InventoryCache.Add(presence.UUID, folders); } void OnClientClosed(UUID clientID, Scene scene) @@ -113,26 +109,64 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory } } - // Drop system folders - lock (m_InventoryCache) - if (m_InventoryCache.ContainsKey(clientID)) - { - m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping system folders", - scene.RegionInfo.RegionName, clientID); - - m_InventoryCache.Remove(clientID); - } + m_log.DebugFormat( + "[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping system folders", + scene.RegionInfo.RegionName, clientID); + DropCachedSystemFolders(clientID); } } + /// + /// Cache a user's 'system' folders. + /// + /// + /// Folders cached + protected Dictionary CacheSystemFolders(UUID userID) + { + // If not, go get them and place them in the cache + Dictionary folders = m_Connector.GetSystemFolders(userID); + if (folders.Count > 0) + lock (m_InventoryCache) + m_InventoryCache.Add(userID, folders); + + return folders; + } + + /// + /// Drop a user's cached 'system' folders + /// + /// + protected void DropCachedSystemFolders(UUID userID) + { + // Drop system folders + lock (m_InventoryCache) + if (m_InventoryCache.ContainsKey(userID)) + m_InventoryCache.Remove(userID); + } + + /// + /// Get the system folder for a particular asset type + /// + /// + /// + /// public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) { Dictionary folders = null; + lock (m_InventoryCache) { m_InventoryCache.TryGetValue(userID, out folders); + + // In some situations (such as non-secured standalones), system folders can be requested without + // the user being logged in. So we need to try caching them here if we don't already have them. + if (null == folders) + CacheSystemFolders(userID); + + m_InventoryCache.TryGetValue(userID, out folders); } + if ((folders != null) && folders.ContainsKey(type)) { return folders[type]; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 33015365cf..650fc7ebf5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -535,7 +535,9 @@ namespace OpenSim.Region.Framework.Scenes } UUID newFolderId = UUID.Random(); - InventoryFolderBase newFolder = new InventoryFolderBase(newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version); + InventoryFolderBase newFolder + = new InventoryFolderBase( + newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version); InventoryService.AddFolder(newFolder); // Give all the subfolders diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index d3e414faa9..55b100b0db 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -472,8 +472,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// null if the inventory look up failed - public List HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, - bool fetchFolders, bool fetchItems, int sortOrder) + public InventoryCollection HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder, out int version) { // m_log.DebugFormat( // "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", @@ -487,11 +487,31 @@ namespace OpenSim.Region.Framework.Scenes InventoryFolderImpl fold; if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null) { - return fold.RequestListOfItems(); + version = 0; + InventoryCollection ret = new InventoryCollection(); + ret.Folders = new List(); + ret.Items = fold.RequestListOfItems(); + + return ret; } InventoryCollection contents = InventoryService.GetFolderContent(agentID, folderID); - return contents.Items; + + if (folderID != UUID.Zero) + { + InventoryFolderBase containingFolder = new InventoryFolderBase(); + containingFolder.ID = folderID; + containingFolder.Owner = agentID; + containingFolder = InventoryService.GetFolder(containingFolder); + version = containingFolder.Version; + } + else + { + // Lost itemsm don't really need a version + version = 1; + } + + return contents; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b1c357c002..0de5c9b59e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -852,6 +852,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return drawList; } + public string osDrawPolygon(string drawList, LSL_List x, LSL_List y) + { + CheckThreatLevel(ThreatLevel.None, "osDrawFilledPolygon"); + + m_host.AddScriptLPS(1); + + if (x.Length != y.Length || x.Length < 3) + { + return ""; + } + drawList += "Polygon " + x.GetLSLStringItem(0) + "," + y.GetLSLStringItem(0); + for (int i = 1; i < x.Length; i++) + { + drawList += "," + x.GetLSLStringItem(i) + "," + y.GetLSLStringItem(i); + } + drawList += "; "; + return drawList; + } + public string osSetFontSize(string drawList, int fontSize) { CheckThreatLevel(ThreatLevel.None, "osSetFontSize"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 2365beeb71..b129b390f0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -97,6 +97,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osDrawEllipse(string drawList, int width, int height); string osDrawRectangle(string drawList, int width, int height); string osDrawFilledRectangle(string drawList, int width, int height); + string osDrawPolygon(string drawList, LSL_List x, LSL_List y); string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y); string osSetFontSize(string drawList, int fontSize); string osSetPenSize(string drawList, int penSize); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index f877acb7e9..45492dd6e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -267,6 +267,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osDrawFilledRectangle(drawList, width, height); } + public string osDrawPolygon(string drawList, LSL_List x, LSL_List y) + { + return m_OSSL_Functions.osDrawPolygon(drawList, x, y); + } + public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y) { return m_OSSL_Functions.osDrawFilledPolygon(drawList, x, y); diff --git a/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs b/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs index 3de224590e..c0933a8607 100644 --- a/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs +++ b/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs @@ -110,12 +110,13 @@ namespace OpenSim.Server.Handlers.Neighbour httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized; return result; } - if (!m_AuthenticationService.VerifyKey(regionID, authToken)) - { - m_log.InfoFormat("[RegionPostHandler]: Authentication failed for neighbour message {0}", path); - httpResponse.StatusCode = (int)HttpStatusCode.Forbidden; - return result; - } + // TODO: Rethink this + //if (!m_AuthenticationService.VerifyKey(regionID, authToken)) + //{ + // m_log.InfoFormat("[RegionPostHandler]: Authentication failed for neighbour message {0}", path); + // httpResponse.StatusCode = (int)HttpStatusCode.Forbidden; + // return result; + //} m_log.DebugFormat("[RegionPostHandler]: Authentication succeeded for {0}", regionID); } diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 6c0b70555f..822edcbc0c 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -109,12 +109,13 @@ namespace OpenSim.Server.Handlers.Simulation httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized; return result; } - if (!m_AuthenticationService.VerifyKey(agentID, authToken)) - { - m_log.InfoFormat("[AgentPostHandler]: Authentication failed for agent message {0}", path); - httpResponse.StatusCode = (int)HttpStatusCode.Forbidden; - return result; - } + // TODO: Rethink this + //if (!m_AuthenticationService.VerifyKey(agentID, authToken)) + //{ + // m_log.InfoFormat("[AgentPostHandler]: Authentication failed for agent message {0}", path); + // httpResponse.StatusCode = (int)HttpStatusCode.Forbidden; + // return result; + //} m_log.DebugFormat("[AgentPostHandler]: Authentication succeeded for {0}", agentID); } diff --git a/OpenSim/Services/AuthenticationService/AuthenticationService.cs b/OpenSim/Services/AuthenticationService/AuthenticationService.cs deleted file mode 100644 index b81a00486c..0000000000 --- a/OpenSim/Services/AuthenticationService/AuthenticationService.cs +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using Nini.Config; -using log4net; -using OpenSim.Framework; -using OpenSim.Data; -using OpenSim.Services.Base; -using OpenSim.Services.Interfaces; -using OpenMetaverse; - -namespace OpenSim.Services.AuthenticationService -{ - /// - /// Simple authentication service implementation dealing only with users. - /// It uses the user DB directly to access user information. - /// It takes two config vars: - /// - Authenticate = {true|false} : to do or not to do authentication - /// - Authority = string like "osgrid.org" : this identity authority - /// that will be called back for identity verification - /// - public class HGAuthenticationService : ServiceBase, IAuthenticationService - { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected IUserDataPlugin m_Database; - protected string m_AuthorityURL; - protected bool m_PerformAuthentication; - protected Dictionary> m_UserKeys = new Dictionary>(); - - - public HGAuthenticationService(IConfigSource config) : base(config) - { - string dllName = String.Empty; - string connString = String.Empty; - - // - // Try reading the [DatabaseService] section first, if it exists - // - IConfig dbConfig = config.Configs["DatabaseService"]; - if (dbConfig != null) - { - dllName = dbConfig.GetString("StorageProvider", String.Empty); - connString = dbConfig.GetString("ConnectionString", String.Empty); - } - - // - // Try reading the more specific [InventoryService] section, if it exists - // - IConfig authConfig = config.Configs["AuthenticationService"]; - if (authConfig != null) - { - dllName = authConfig.GetString("StorageProvider", dllName); - connString = authConfig.GetString("ConnectionString", connString); - - m_PerformAuthentication = authConfig.GetBoolean("Authenticate", true); - m_AuthorityURL = "http://" + authConfig.GetString("Authority", "localhost"); - if (!m_AuthorityURL.EndsWith("/")) - m_AuthorityURL += "/"; - } - - // - // We tried, but this doesn't exist. We can't proceed. - // - if (dllName.Equals(String.Empty)) - throw new Exception("No InventoryService configuration"); - - m_Database = LoadPlugin(dllName); - if (m_Database == null) - throw new Exception("Could not find a storage interface in the given module"); - - m_Database.Initialise(connString); - } - - public UUID AuthenticateKey(UUID principalID, string key) - { - bool writeAgentData = false; - - UserAgentData agent = m_Database.GetAgentByUUID(principalID); - if (agent == null) - { - agent = new UserAgentData(); - agent.ProfileID = principalID; - agent.SessionID = UUID.Random(); - agent.SecureSessionID = UUID.Random(); - agent.AgentIP = "127.0.0.1"; - agent.AgentPort = 0; - agent.AgentOnline = false; - - writeAgentData = true; - } - - if (!m_PerformAuthentication) - { - if (writeAgentData) - m_Database.AddNewUserAgent(agent); - return agent.SessionID; - } - - if (!VerifyKey(principalID, key)) - return UUID.Zero; - - if (writeAgentData) - m_Database.AddNewUserAgent(agent); - - return agent.SessionID; - } - - /// - /// This implementation only authenticates users. - /// - /// - /// - /// - public UUID AuthenticatePassword(UUID principalID, string password) - { - bool writeAgentData = false; - - UserAgentData agent = m_Database.GetAgentByUUID(principalID); - if (agent == null) - { - agent = new UserAgentData(); - agent.ProfileID = principalID; - agent.SessionID = UUID.Random(); - agent.SecureSessionID = UUID.Random(); - agent.AgentIP = "127.0.0.1"; - agent.AgentPort = 0; - agent.AgentOnline = false; - - writeAgentData = true; - } - - if (!m_PerformAuthentication) - { - if (writeAgentData) - m_Database.AddNewUserAgent(agent); - return agent.SessionID; - } - - UserProfileData profile = m_Database.GetUserByUUID(principalID); - bool passwordSuccess = false; - m_log.InfoFormat("[AUTH]: Authenticating {0} {1} ({2})", profile.FirstName, profile.SurName, profile.ID); - - // we do this to get our hash in a form that the server password code can consume - // when the web-login-form submits the password in the clear (supposed to be over SSL!) - if (!password.StartsWith("$1$")) - password = "$1$" + Util.Md5Hash(password); - - password = password.Remove(0, 3); //remove $1$ - - string s = Util.Md5Hash(password + ":" + profile.PasswordSalt); - // Testing... - //m_log.Info("[LOGIN]: SubHash:" + s + " userprofile:" + profile.passwordHash); - //m_log.Info("[LOGIN]: userprofile:" + profile.passwordHash + " SubCT:" + password); - - passwordSuccess = (profile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase) - || profile.PasswordHash.Equals(password, StringComparison.InvariantCulture)); - - if (!passwordSuccess) - return UUID.Zero; - - if (writeAgentData) - m_Database.AddNewUserAgent(agent); - - return agent.SessionID; - } - - /// - /// This generates authorization keys in the form - /// http://authority/uuid - /// after verifying that the caller is, indeed, authorized to request a key - /// - /// The principal ID requesting the new key - /// The original authorization token for that principal, obtained during login - /// - public string GetKey(UUID principalID, string authToken) - { - UserProfileData profile = m_Database.GetUserByUUID(principalID); - string newKey = string.Empty; - - if (profile != null) - { - m_log.DebugFormat("[AUTH]: stored auth token is {0}. Given token is {1}", profile.WebLoginKey.ToString(), authToken); - // I'm overloading webloginkey for this, so that no changes are needed in the DB - // The uses of webloginkey are fairly mutually exclusive - if (profile.WebLoginKey.ToString().Equals(authToken)) - { - newKey = UUID.Random().ToString(); - List keys; - lock (m_UserKeys) - { - if (m_UserKeys.ContainsKey(principalID)) - { - keys = m_UserKeys[principalID]; - } - else - { - keys = new List(); - m_UserKeys.Add(principalID, keys); - } - keys.Add(newKey); - } - m_log.InfoFormat("[AUTH]: Successfully generated new auth key for {0}", principalID); - } - else - m_log.Warn("[AUTH]: Unauthorized key generation request. Denying new key."); - } - else - m_log.Warn("[AUTH]: Principal not found."); - - return m_AuthorityURL + newKey; - } - - /// - /// This verifies the uuid portion of the key given out by GenerateKey - /// - /// - /// - /// - public bool VerifyKey(UUID userID, string key) - { - lock (m_UserKeys) - { - if (m_UserKeys.ContainsKey(userID)) - { - List keys = m_UserKeys[userID]; - if (keys.Contains(key)) - { - // Keys are one-time only, so remove it - keys.Remove(key); - return true; - } - return false; - } - else - return false; - } - } - - public UUID CreateUserSession(UUID userID, UUID oldSessionID) - { - UserAgentData agent = m_Database.GetAgentByUUID(userID); - - if (agent == null) - return UUID.Zero; - - agent.SessionID = UUID.Random(); - - m_Database.AddNewUserAgent(agent); - return agent.SessionID; - } - - public bool VerifyUserSession(UUID userID, UUID sessionID) - { - UserProfileData userProfile = m_Database.GetUserByUUID(userID); - - if (userProfile != null && userProfile.CurrentAgent != null) - { - m_log.DebugFormat("[AUTH]: Verifying session {0} for {1}; current session {2}", sessionID, userID, userProfile.CurrentAgent.SessionID); - if (userProfile.CurrentAgent.SessionID == sessionID) - { - return true; - } - } - - return false; - } - - public bool DestroyUserSession(UUID userID, UUID sessionID) - { - if (!VerifyUserSession(userID, sessionID)) - return false; - - UserAgentData agent = m_Database.GetAgentByUUID(userID); - if (agent == null) - return false; - - agent.SessionID = UUID.Zero; - m_Database.AddNewUserAgent(agent); - - return true; - } - } -} diff --git a/OpenSim/Services/Interfaces/IAuthenticationService.cs b/OpenSim/Services/Interfaces/IAuthenticationService.cs index 24024144ee..d473cf8ac7 100644 --- a/OpenSim/Services/Interfaces/IAuthenticationService.cs +++ b/OpenSim/Services/Interfaces/IAuthenticationService.cs @@ -38,57 +38,89 @@ namespace OpenSim.Services.Interfaces // public interface IAuthenticationService { - ////////////////////////////////////////////////// - // Web login key portion + ////////////////////////////////////////////////////// + // PKI Zone! // + // HG2 authentication works by using a cryptographic + // exchange. + // This method must provide a public key, the other + // crypto methods must understand hoow to deal with + // messages encrypted to it. + // + // If the public key is of zero length, you will + // get NO encryption and NO security. + // + // For non-HG installations, this is not relevant + // + // Implementors who are not using PKI can treat the + // cyphertext as a string and provide a zero-length + // key. Encryptionless implementations will not + // interoperate with implementations using encryption. + // If one side uses encryption, both must do so. + // + byte[] GetPublicKey(); - // Get a service key given that principal's - // authentication token (master key). + ////////////////////////////////////////////////////// + // Authentication // - string GetKey(UUID principalID, string authToken); + // These methods will return a token, which can be used to access + // various services. + // + // The encrypted versions take the received cyphertext and + // the public key of the peer, which the connector must have + // obtained using a remote GetPublicKey call. + // + string AuthenticatePassword(UUID principalID, string password); + byte[] AuthenticatePasswordEncrypted(byte[] cyphertext, byte[] key); - // Verify that a principal key is valid - // - bool VerifyKey(UUID principalID, string key); + string AuthenticateWebkey(UUID principalID, string webkey); + byte[] AuthenticateWebkeyEncrypted(byte[] cyphertext, byte[] key); - ////////////////////////////////////////////////// - // Password auth portion + ////////////////////////////////////////////////////// + // Verification // + // Allows to verify the authenticity of a token + // + // Tokens expire after 30 minutes and can be refreshed by + // re-verifying. + // + // If encrypted authentication was used, encrypted verification + // must be used to refresh. Unencrypted verification is still + // performed, but doesn't refresh token lifetime. + // + bool Verify(UUID principalID, string token); + bool VerifyEncrypted(byte[] cyphertext, byte[] key); - // Here's how thos works, and why. + ////////////////////////////////////////////////////// + // Teardown // - // The authentication methods will return the existing session, - // or UUID.Zero if authentication failed. If there is no session, - // they will create one. - // The CreateUserSession method will unconditionally create a session - // and invalidate the prior session. - // Grid login uses this method to make sure that the session is - // fresh and new. Other software, like management applications, - // can obtain this existing session if they have a key or password - // for that account, this allows external apps to obtain credentials - // and use authenticating interface methods. + // A token can be returned before the timeout. This + // invalidates it and it can not subsequently be used + // or refreshed. // - - // Check the pricipal's password + // Tokens created by encrypted authentication must + // be returned by encrypted release calls; // - UUID AuthenticatePassword(UUID principalID, string password); + bool Release(UUID principalID, string token); + bool ReleaseEncrypted(byte[] cyphertext, byte[] key); - // Check the principal's key + ////////////////////////////////////////////////////// + // Grid // - UUID AuthenticateKey(UUID principalID, string password); + // We no longer need a shared secret between grid + // servers. Anything a server requests from another + // server is either done on behalf of a user, in which + // case there is a token, or on behalf of a region, + // which has a session. So, no more keys. + // If sniffing on the local lan is an issue, admins + // need to take approriate action (IPSec is recommended) + // to secure inter-server traffic. - // Create a new session, invalidating the old ones + ////////////////////////////////////////////////////// + // NOTE // - UUID CreateUserSession(UUID principalID, UUID oldSessionID); - - // Verify that a user session ID is valid. A session ID is - // considered valid when a user has successfully authenticated - // at least one time inside that session. - // - bool VerifyUserSession(UUID principalID, UUID sessionID); - - // Deauthenticate user - // - bool DestroyUserSession(UUID principalID, UUID sessionID); + // Session IDs are not handled here. After obtaining + // a token, the session ID regions use can be + // obtained from the presence service. } } diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs index 19b1fd87fa..f04754b195 100644 --- a/OpenSim/Services/InventoryService/InventoryService.cs +++ b/OpenSim/Services/InventoryService/InventoryService.cs @@ -88,6 +88,8 @@ namespace OpenSim.Services.InventoryService // See IInventoryServices public virtual InventoryFolderBase GetRootFolder(UUID userID) { + //m_log.DebugFormat("[INVENTORY SERVICE]: Getting root folder for {0}", userID); + // Retrieve the first root folder we get from the DB. InventoryFolderBase rootFolder = m_Database.getUserRootFolder(userID); if (rootFolder != null) diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index 1b14abbf1f..ce116f2d6e 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Data; @@ -39,7 +41,9 @@ namespace OpenSim.Tests.Common.Mock /// tests are single threaded. /// public class TestInventoryDataPlugin : IInventoryDataPlugin - { + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// /// Inventory folders /// @@ -87,6 +91,8 @@ namespace OpenSim.Tests.Common.Mock public InventoryFolderBase getUserRootFolder(UUID user) { + m_log.DebugFormat("[MOCK INV DB]: Looking for root folder for {0}", user); + InventoryFolderBase folder = null; m_rootFolders.TryGetValue(user, out folder); @@ -124,7 +130,11 @@ namespace OpenSim.Tests.Common.Mock m_folders[folder.ID] = folder; if (folder.ParentID == UUID.Zero) + { + m_log.DebugFormat( + "[MOCK INV DB]: Adding root folder {0} {1} for {2}", folder.Name, folder.ID, folder.Owner); m_rootFolders[folder.Owner] = folder; + } } public void updateInventoryFolder(InventoryFolderBase folder) diff --git a/bin/OpenSim.Data.MySQL.Tests.dll.config b/bin/OpenSim.Data.MySQL.Tests.dll.config deleted file mode 100644 index a3f681d89e..0000000000 --- a/bin/OpenSim.Data.MySQL.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Data.NHibernate.Tests.dll.config b/bin/OpenSim.Data.NHibernate.Tests.dll.config deleted file mode 100644 index 9b3231f610..0000000000 --- a/bin/OpenSim.Data.NHibernate.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Data.SQLite.Tests.dll.config b/bin/OpenSim.Data.SQLite.Tests.dll.config deleted file mode 100644 index a3f681d89e..0000000000 --- a/bin/OpenSim.Data.SQLite.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Data.Tests.dll.config b/bin/OpenSim.Data.Tests.dll.config deleted file mode 100644 index a3f681d89e..0000000000 --- a/bin/OpenSim.Data.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index cff5d19097..2303873dd4 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1366,6 +1366,13 @@ ; ;TextureDataLimit = 5 +;; The JPEG2000 decode cache +;; Timeout is in minutes + +[J2KDecoder] +;CacheDir = "./j2kDecodeCache" +;CacheTimeout = 720 + ;; ;; These are defaults that are overwritten below in [Architecture]. ;; These defaults allow OpenSim to work out of the box with