aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs103
1 files changed, 101 insertions, 2 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
index 6daae29..9042e0d 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
@@ -27,9 +27,14 @@
27 27
28using System; 28using System;
29using System.CodeDom.Compiler; 29using System.CodeDom.Compiler;
30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Diagnostics;
31using System.IO; 33using System.IO;
32using System.Reflection; 34using System.Reflection;
35using System.Security;
36using System.Security.Permissions;
37using System.Security.Policy;
33using System.Text; 38using System.Text;
34using log4net; 39using log4net;
35using Microsoft.CSharp; 40using Microsoft.CSharp;
@@ -54,6 +59,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
54 59
55 private readonly MicroScheduler m_microthreads = new MicroScheduler(); 60 private readonly MicroScheduler m_microthreads = new MicroScheduler();
56 61
62
63 private IConfig m_config;
64
57 public void RegisterExtension<T>(T instance) 65 public void RegisterExtension<T>(T instance)
58 { 66 {
59 m_extensions[typeof (T)] = instance; 67 m_extensions[typeof (T)] = instance;
@@ -63,6 +71,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
63 { 71 {
64 if (source.Configs["MRM"] != null) 72 if (source.Configs["MRM"] != null)
65 { 73 {
74 m_config = source.Configs["MRM"];
75
66 if (source.Configs["MRM"].GetBoolean("Enabled", false)) 76 if (source.Configs["MRM"].GetBoolean("Enabled", false))
67 { 77 {
68 m_log.Info("[MRM] Enabling MRM Module"); 78 m_log.Info("[MRM] Enabling MRM Module");
@@ -112,6 +122,91 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
112 return script; 122 return script;
113 } 123 }
114 124
125 /// <summary>
126 /// Create an AppDomain that contains policy restricting code to execute
127 /// with only the permissions granted by a named permission set
128 /// </summary>
129 /// <param name="permissionSetName">name of the permission set to restrict to</param>
130 /// <param name="appDomainName">'friendly' name of the appdomain to be created</param>
131 /// <exception cref="ArgumentNullException">
132 /// if <paramref name="permissionSetName"/> is null
133 /// </exception>
134 /// <exception cref="ArgumentOutOfRangeException">
135 /// if <paramref name="permissionSetName"/> is empty
136 /// </exception>
137 /// <returns>AppDomain with a restricted security policy</returns>
138 /// <remarks>Substantial portions of this function from: http://blogs.msdn.com/shawnfa/archive/2004/10/25/247379.aspx
139 /// Valid permissionSetName values are:
140 /// * FullTrust
141 /// * SkipVerification
142 /// * Execution
143 /// * Nothing
144 /// * LocalIntranet
145 /// * Internet
146 /// * Everything
147 /// </remarks>
148 public static AppDomain CreateRestrictedDomain(string permissionSetName, string appDomainName)
149 {
150 if (permissionSetName == null)
151 throw new ArgumentNullException("permissionSetName");
152 if (permissionSetName.Length == 0)
153 throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName,
154 "Cannot have an empty permission set name");
155
156 // Default to all code getting nothing
157 PolicyStatement emptyPolicy = new PolicyStatement(new PermissionSet(PermissionState.None));
158 UnionCodeGroup policyRoot = new UnionCodeGroup(new AllMembershipCondition(), emptyPolicy);
159
160 bool foundName = false;
161 PermissionSet setIntersection = new PermissionSet(PermissionState.Unrestricted);
162
163 // iterate over each policy level
164 IEnumerator levelEnumerator = SecurityManager.PolicyHierarchy();
165 while (levelEnumerator.MoveNext())
166 {
167 PolicyLevel level = levelEnumerator.Current as PolicyLevel;
168
169 // if this level has defined a named permission set with the
170 // given name, then intersect it with what we've retrieved
171 // from all the previous levels
172 if (level != null)
173 {
174 PermissionSet levelSet = level.GetNamedPermissionSet(permissionSetName);
175 if (levelSet != null)
176 {
177 foundName = true;
178 if (setIntersection != null)
179 setIntersection = setIntersection.Intersect(levelSet);
180 }
181 }
182 }
183
184 // Intersect() can return null for an empty set, so convert that
185 // to an empty set object. Also return an empty set if we didn't find
186 // the named permission set we were looking for
187 if (setIntersection == null || !foundName)
188 setIntersection = new PermissionSet(PermissionState.None);
189 else
190 setIntersection = new NamedPermissionSet(permissionSetName, setIntersection);
191
192 // if no named permission sets were found, return an empty set,
193 // otherwise return the set that was found
194 PolicyStatement permissions = new PolicyStatement(setIntersection);
195 policyRoot.AddChild(new UnionCodeGroup(new AllMembershipCondition(), permissions));
196
197 // create an AppDomain policy level for the policy tree
198 PolicyLevel appDomainLevel = PolicyLevel.CreateAppDomainLevel();
199 appDomainLevel.RootCodeGroup = policyRoot;
200
201 // create an AppDomain where this policy will be in effect
202 string domainName = appDomainName;
203 AppDomain restrictedDomain = AppDomain.CreateDomain(domainName);
204 restrictedDomain.SetAppDomainPolicy(appDomainLevel);
205
206 return restrictedDomain;
207 }
208
209
115 void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) 210 void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource)
116 { 211 {
117 if (script.StartsWith("//MRM:C#")) 212 if (script.StartsWith("//MRM:C#"))
@@ -125,9 +220,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
125 220
126 try 221 try
127 { 222 {
128 m_log.Info("[MRM] Found C# MRM"); 223 m_log.Info("[MRM] Found C# MRM - Starting in AppDomain with " + m_config.GetString("permissionLevel", "Internet") + "-level security.");
224
225 string domainName = UUID.Random().ToString();
226 AppDomain target = CreateRestrictedDomain(m_config.GetString("permissionLevel", "Internet"),
227 domainName);
129 228
130 MRMBase mmb = (MRMBase)AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap( 229 MRMBase mmb = (MRMBase) target.CreateInstanceFromAndUnwrap(
131 CompileFromDotNetText(script, itemID.ToString()), 230 CompileFromDotNetText(script, itemID.ToString()),
132 "OpenSim.MiniModule"); 231 "OpenSim.MiniModule");
133 232