From 3089b6d824f1d4eb25ba12c5fd037153fdc92e1e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 20 Sep 2012 15:49:22 -0700 Subject: [PATCH] More HG2.0: Added permission policies in HGAsset Service based on asset types. The policies are given in the config. This is only half of the story. The other half, pertaining to exports/imports made by the sim, will be done next. --- .../InventoryAccess/HGAssetMapper.cs | 34 ++++---- .../HypergridService/HGAssetService.cs | 79 ++++++++++++++++++- bin/Robust.HG.ini.example | 10 +++ .../StandaloneCommon.ini.example | 11 +++ 4 files changed, 116 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index eaadc1b8be..fcecbbcde5 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs @@ -93,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (!url.EndsWith("/") && !url.EndsWith("=")) url = url + "/"; + bool success = true; // See long comment in AssetCache.AddAsset if (!asset.Temporary || asset.Local) { @@ -103,14 +104,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // not having a global naming infrastructure AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); Copy(asset, asset1); - try - { - asset1.ID = url + asset.ID; - } - catch - { - m_log.Warn("[HG ASSET MAPPER]: Oops."); - } + asset1.ID = url + asset.ID; AdjustIdentifiers(asset1.Metadata); if (asset1.Metadata.Type == (sbyte)AssetType.Object) @@ -118,11 +112,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else asset1.Data = asset.Data; - m_scene.AssetService.Store(asset1); - m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); + string id = m_scene.AssetService.Store(asset1); + if (id == UUID.Zero.ToString()) + { + m_log.DebugFormat("[HG ASSET MAPPER]: Asset server {0} did not accept {1}", url, asset.ID); + success = false; + } + else + m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); } - return true; - } + return success; + } else m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache."); @@ -259,17 +259,21 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess Dictionary ids = new Dictionary(); HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty); uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); + bool success = false; foreach (UUID uuid in ids.Keys) { asset = m_scene.AssetService.Get(uuid.ToString()); if (asset == null) m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); else - PostAsset(userAssetURL, asset); + success = PostAsset(userAssetURL, asset); } - // maybe all pieces got there... - m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); + // maybe all pieces got there... + if (!success) + m_log.DebugFormat("[HG ASSET MAPPER]: Problems posting item {0} to asset server {1}", assetID, userAssetURL); + else + m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); } else diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs index db9816639b..d6541c425d 100644 --- a/OpenSim/Services/HypergridService/HGAssetService.cs +++ b/OpenSim/Services/HypergridService/HGAssetService.cs @@ -58,6 +58,9 @@ namespace OpenSim.Services.HypergridService private UserAccountCache m_Cache; + private bool[] m_DisallowGET, m_DisallowPOST; + private string[] m_AssetTypeNames; + public HGAssetService(IConfigSource config, string configName) : base(config, configName) { m_log.Debug("[HGAsset Service]: Starting"); @@ -80,6 +83,34 @@ namespace OpenSim.Services.HypergridService m_HomeURL = assetConfig.GetString("HomeURI", m_HomeURL); m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); + + // Permissions + Type enumType = typeof(AssetType); + m_AssetTypeNames = Enum.GetNames(enumType); + for (int i = 0; i < m_AssetTypeNames.Length; i++) + m_AssetTypeNames[i] = m_AssetTypeNames[i].ToLower(); + int n = Enum.GetValues(enumType).Length; + m_DisallowGET = new bool[n]; + m_DisallowPOST = new bool[n]; + + LoadPermsFromConfig(assetConfig, "DisallowGET", m_DisallowGET); + LoadPermsFromConfig(assetConfig, "DisallowPOST", m_DisallowPOST); + + } + + private void LoadPermsFromConfig(IConfig assetConfig, string variable, bool[] bitArray) + { + string perms = assetConfig.GetString(variable, String.Empty); + string[] parts = perms.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries); + foreach (string s in parts) + { + int index = Array.IndexOf(m_AssetTypeNames, s.Trim().ToLower()); + if (index >= 0) + bitArray[index] = true; + else + m_log.WarnFormat("[HGAsset Service]: Invalid AssetType {0}", s); + } + } #region IAssetService overrides @@ -90,6 +121,9 @@ namespace OpenSim.Services.HypergridService if (asset == null) return null; + if (!AllowedGet(asset.Type)) + return null; + if (asset.Metadata.Type == (sbyte)AssetType.Object) asset.Data = AdjustIdentifiers(asset.Data); ; @@ -112,16 +146,27 @@ namespace OpenSim.Services.HypergridService public override byte[] GetData(string id) { - byte[] data = base.GetData(id); + AssetBase asset = Get(id); - if (data == null) + if (asset == null) return null; - return AdjustIdentifiers(data); + if (!AllowedGet(asset.Type)) + return null; + + return asset.Data; } //public virtual bool Get(string id, Object sender, AssetRetrieved handler) + public override string Store(AssetBase asset) + { + if (!AllowedPost(asset.Type)) + return UUID.Zero.ToString(); + + return base.Store(asset); + } + public override bool Delete(string id) { // NOGO @@ -130,6 +175,34 @@ namespace OpenSim.Services.HypergridService #endregion + protected bool AllowedGet(sbyte type) + { + string assetTypeName = ((AssetType)type).ToString(); + + int index = Array.IndexOf(m_AssetTypeNames, assetTypeName.ToLower()); + if (index >= 0 && m_DisallowGET[index]) + { + m_log.DebugFormat("[HGAsset Service]: GET denied: service does not allow export of AssetType {0}", assetTypeName); + return false; + } + + return true; + } + + protected bool AllowedPost(sbyte type) + { + string assetTypeName = ((AssetType)type).ToString(); + + int index = Array.IndexOf(m_AssetTypeNames, assetTypeName.ToLower()); + if (index >= 0 && m_DisallowPOST[index]) + { + m_log.DebugFormat("[HGAsset Service]: POST denied: service does not allow import of AssetType {0}", assetTypeName); + return false; + } + + return true; + } + protected void AdjustIdentifiers(AssetMetadata meta) { if (meta == null || m_Cache == null) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index fad399d351..8218b14d4d 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -437,6 +437,16 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" HomeURI = "http://127.0.0.1:8002" + ;; The asset types that other grids can get from / post to this service. + ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely: + ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh + ;; + ;; Leave blank or commented if you don't want to apply any restrictions. + ;; A more strict, but still reasonable, policy may be to disallow the exchange + ;; of scripts, like so: + ; DisallowGET ="LSLText" + ; DisallowPOST ="LSLBytecode" + [HGFriendsService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService" UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index e4bc548967..d8ecba8d11 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -53,6 +53,17 @@ [HGAssetService] HomeURI = "http://127.0.0.1:9000" + ;; The asset types that other grids can get from / post to this service. + ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely: + ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh + ;; + ;; Leave blank or commented if you don't want to apply any restrictions. + ;; A more strict, but still reasonable, policy may be to disallow the exchange + ;; of scripts, like so: + ; DisallowGET ="LSLText" + ; DisallowPOST ="LSLBytecode" + + [HGInventoryAccessModule] HomeURI = "http://127.0.0.1:9000" Gatekeeper = "http://127.0.0.1:9000"