From 7223b63563f28f6fe8044bdabcd1b9900d28c54a Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 27 Mar 2012 22:09:58 +0200 Subject: [PATCH] User level based restrictions for HyperGrid teleports, asset uploads, group creations and getting contacted from other grids. Incoming HyperGrid teleports can also be restricted to local users. --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 36 ++++++++++++---- ...ewFileAgentInventoryVariablePriceModule.cs | 42 +++++++++++++------ .../AssetTransactionModule.cs | 22 +++++++++- .../EntityTransfer/EntityTransferModule.cs | 15 +++++++ .../Avatar/XmlRpcGroups/GroupsModule.cs | 22 +++++++++- .../Shared/Api/Implementation/LSL_Api.cs | 3 ++ .../HypergridService/GatekeeperService.cs | 13 ++++++ .../HypergridService/UserAgentService.cs | 14 ++++++- bin/OpenSimDefaults.ini | 12 ++++++ bin/Robust.HG.ini.example | 3 ++ .../StandaloneCommon.ini.example | 7 ++++ 11 files changed, 164 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index ed3430a319..8ec2f200bb 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -111,6 +111,7 @@ namespace OpenSim.Region.ClientStack.Linden private IAssetService m_assetService; private bool m_dumpAssetsToFile = false; private string m_regionName; + private int m_levelUpload = 0; public BunchOfCaps(Scene scene, Caps caps) { @@ -121,7 +122,10 @@ namespace OpenSim.Region.ClientStack.Linden { IConfig sconfig = config.Configs["Startup"]; if (sconfig != null) + { m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); + m_levelUpload = sconfig.GetInt("LevelUpload", 0); + } } m_assetService = m_Scene.AssetService; @@ -357,21 +361,37 @@ namespace OpenSim.Region.ClientStack.Linden llsdRequest.asset_type == "animation" || llsdRequest.asset_type == "sound") { + ScenePresence avatar = null; IClientAPI client = null; - IScene scene = null; - if (GetClient != null) - { - client = GetClient(m_HostCapsObj.AgentID); - scene = client.Scene; + m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar); - IMoneyModule mm = scene.RequestModuleInterface(); + // check user level + if (avatar != null) + { + client = avatar.ControllingClient; + + if (avatar.UserLevel < m_levelUpload) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + + LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); + errorResponse.uploader = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + + // check funds + if (client != null) + { + IMoneyModule mm = m_Scene.RequestModuleInterface(); if (mm != null) { if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); errorResponse.uploader = ""; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index 1117f2a8a6..91872c5a34 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden // private IAssetService m_assetService; private bool m_dumpAssetsToFile = false; private bool m_enabled = true; + private int m_levelUpload = 0; #region IRegionModuleBase Members @@ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden return; m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); + m_levelUpload = meshConfig.GetInt("LevelUpload", 0); } public void AddRegion(Scene pScene) @@ -137,25 +139,41 @@ namespace OpenSim.Region.ClientStack.Linden // llsdRequest.asset_type == "animation" || // llsdRequest.asset_type == "sound") // { + // check user level + ScenePresence avatar = null; IClientAPI client = null; + m_scene.TryGetScenePresence(agentID, out avatar); - + if (avatar != null) + { + client = avatar.ControllingClient; + + if (avatar.UserLevel < m_levelUpload) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + + // check funds IMoneyModule mm = m_scene.RequestModuleInterface(); - + if (mm != null) { - if (m_scene.TryGetClient(agentID, out client)) + if (!mm.UploadCovered(agentID, mm.UploadCharge)) { - if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); - LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - errorResponse.rsvp = ""; - errorResponse.state = "error"; - return errorResponse; - } + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; } } // } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 95e3aeceb1..874693e8ea 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -47,6 +47,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction protected Scene m_Scene; private bool m_dumpAssetsToFile = false; + private int m_levelUpload = 0; /// /// Each agent has its own singleton collection of transactions @@ -56,8 +57,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(IConfigSource source) { + IConfig sconfig = source.Configs["Startup"]; + if (sconfig != null) + { + m_levelUpload = sconfig.GetInt("LevelUpload", 0); + } } public void AddRegion(Scene scene) @@ -241,7 +247,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction (AssetType)type == AssetType.Animation) && tempFile == false) { + ScenePresence avatar = null; Scene scene = (Scene)remoteClient.Scene; + scene.TryGetScenePresence(remoteClient.AgentId, out avatar); + + // check user level + if (avatar != null) + { + if (avatar.UserLevel < m_levelUpload) + { + remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + return; + } + } + + // check funds IMoneyModule mm = scene.RequestModuleInterface(); if (mm != null) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 2d73594189..427a49d248 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -60,6 +60,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer set { m_MaxTransferDistance = value; } } + private int m_levelHGTeleport = 0; + protected bool m_Enabled = false; protected Scene m_aScene; protected List m_Scenes = new List(); @@ -101,7 +103,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) + { MaxTransferDistance = transferConfig.GetInt("max_distance", 4095); + m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); + } m_agentsInTransit = new List(); m_Enabled = true; @@ -227,6 +232,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + // check if HyperGrid teleport is allowed, based on user level + int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID); + + if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport)) + { + m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); + sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted"); + return; + } + uint curX = 0, curY = 0; Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); int curCellX = (int)(curX / Constants.RegionSize); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b60cd4206f..ea5d80568a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; private bool m_debugEnabled = false; + private int m_levelGroupCreate = 0; #region IRegionModuleBase Members @@ -115,6 +116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); + m_levelGroupCreate = groupsConfig.GetInt("LevelGroupCreate", 0); } } @@ -708,13 +710,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } + + // check user level + ScenePresence avatar = null; + Scene scene = (Scene)remoteClient.Scene; + scene.TryGetScenePresence(remoteClient.AgentId, out avatar); + + if (avatar != null) + { + if (avatar.UserLevel < m_levelGroupCreate) + { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient permissions to create a group."); + return UUID.Zero; + } + } + + // check funds // is there is a money module present ? - IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); + IMoneyModule money = scene.RequestModuleInterface(); if (money != null) { // do the transaction, that is if the agent has got sufficient funds if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); return UUID.Zero; } money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d7a629bf8b..745592940d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4151,6 +4151,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case 4: // DATA_RATING (0,0,0,0,0,0) reply = "0,0,0,0,0,0"; break; + case 7: // DATA_USERLEVEL (integer) + reply = account.UserLevel.ToString(); + break; case 8: // DATA_PAYINFO (0|1|2|3) reply = "0"; break; diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 4e386879cc..149a0abb4f 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -60,6 +60,7 @@ namespace OpenSim.Services.HypergridService protected string m_AllowedClients = string.Empty; protected string m_DeniedClients = string.Empty; + private static bool m_ForeignAgentsAllowed = true; private static UUID m_ScopeID; private static bool m_AllowTeleportsToAnyRegion; @@ -110,6 +111,7 @@ namespace OpenSim.Services.HypergridService m_AllowedClients = serverConfig.GetString("AllowedClients", string.Empty); m_DeniedClients = serverConfig.GetString("DeniedClients", string.Empty); + m_ForeignAgentsAllowed = serverConfig.GetBoolean("ForeignAgentsAllowed", true); if (m_GridService == null || m_PresenceService == null || m_SimulationService == null) throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); @@ -257,6 +259,17 @@ namespace OpenSim.Services.HypergridService } m_log.DebugFormat("[GATEKEEPER SERVICE]: User is ok"); + // + // Foreign agents allowed + // + if (account == null && !m_ForeignAgentsAllowed) + { + reason = "Unauthorized"; + m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agents are not permitted {0} {1}. Refusing service.", + aCircuit.firstname, aCircuit.lastname); + return false; + } + // May want to authorize bool isFirstLogin = false; diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 6a5007ff26..49c7f89598 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -73,6 +73,8 @@ namespace OpenSim.Services.HypergridService protected static string m_GridName; + protected static int m_LevelOutsideContacts; + protected static bool m_BypassClientVerification; public UserAgentService(IConfigSource config) : this(config, null) @@ -127,6 +129,8 @@ namespace OpenSim.Services.HypergridService } if (!m_GridName.EndsWith("/")) m_GridName = m_GridName + "/"; + + m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0); } } @@ -571,10 +575,16 @@ namespace OpenSim.Services.HypergridService public UUID GetUUID(String first, String last) { - // Let's see if it's a local user + // Let's see if it's a local user UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last); if (account != null) - return account.PrincipalID; + { + // check user level + if (account.UserLevel < m_LevelOutsideContacts) + return UUID.Zero; + else + return account.PrincipalID; + } else return UUID.Zero; } diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 28c5587ad7..45d604f829 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -272,6 +272,8 @@ ; Disabled by default ; simple_build_permissions = False + ; Minimum user level required to upload assets + ;LevelUpload = 0 ; ## ; ## SCRIPT ENGINE @@ -620,6 +622,10 @@ ; This is set to 4095 because current viewers can't handle teleports that are greater than this distance max_distance = 4095 + ; Minimum user level required for HyperGrid teleports + LevelHGTeleport = 0 + + [Messaging] ; Control which region module is used for instant messaging. ; Default is InstantMessageModule (this is the name of the core IM module as well as the setting) @@ -657,6 +663,9 @@ ; mesh, and use it for collisions. UseMeshiesPhysicsMesh = true + ; Minimum user level required to upload meshes + ;LevelUpload = 0 + [ODEPhysicsSettings] ;## @@ -1497,6 +1506,9 @@ ; System.Net.WebException: The request was aborted: The request was canceled. ; XmlRpcDisableKeepAlive = false + ; Minimum user level required to create groups + ;LevelGroupCreate = 0 + [PacketPool] ; Enables the experimental packet pool. Yes, we've been here before. diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index e0242abbef..2fd9f11ba6 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -373,6 +373,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;; the IP address of the machine where your LoginService is ;LoginServerIP = "127.0.0.1" + ; User level required to be contacted from other grids + ;LevelOutsideContacts = 0 + ; * The interface that local users get when they are in other grids. ; * This restricts the inventory operations while in other grids. ; * Still not completely safe, especially if users perform inventory operations diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 3dfbed7fdc..8d9842cc5a 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -147,6 +147,9 @@ ;AllowedClients = "" ;DeniedClients = "" + ;; Are foreign visitors allowed + ;ForeignAgentsAllowed = true + [FreeswitchService] ;; If FreeSWITCH is not being used then you don't need to set any of these parameters ;; @@ -241,3 +244,7 @@ ; DisallowResidents -- only Admins and Managers allowed ; Example: ; Region_Test_1 = "DisallowForeigners" + +[UserAgentService] + ; User level required to be contacted from other grids + ;LevelOutsideContacts = 0