I want to run some of my code in Python. However, for security reasons i need to run it in some kind of sandbox. What I'm doing is: First i create a domain with restricted permissions:
private AppDomain CreateDomain()
{
AppDomainSetup setup = new AppDomainSetup();
Assembly thisAssembly = Assembly.GetExecutingAssembly();
setup.ApplicationBase = Path.GetDirectoryName(thisAssembly.Location);
AssemblyName name = typeof(Program).Assembly.GetName();
StrongName sn = new StrongName(new StrongNamePublicKeyBlob(name.GetPublicKey()), name.Name, name.Version);
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
setup.PartialTrustVisibleAssemblies = new[] { sn.Name + ", PublicKey=" + sn.PublicKey.ToString() };
AppDomain domain = AppDomain.CreateDomain(
"Sandbox",
AppDomain.CurrentDomain.Evidence,
setup,
permSet,
sn);
return domain;
}
Next i create python engine and other needed items(d is a Dictionary which im working on in python:
string pythonCode = File.ReadAllText(@"D:\Python\Class.py");
string createInstanceCode = "ObjectNew = Class(dictionary)";
ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine(domain);
ScriptScope pyScope = pyEngine.CreateScope();
pyScope.SetVariable("dictionary", d);
pyEngine.Execute(pythonCode, pyScope);
pyEngine.Execute(createInstanceCode, pyScope);
The python code is just one big class with functions in it. I want to call these functions from C# and get the results so i try to create an instance of that class. Using advice from this question: How do I call a specific Method from a Python Script in C#? I am doing this:
var testObject = pyScope.GetVariable("ObjectNew");
This is the error i get at this point: An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in PythonTimeTests.exe
This doesn't happen if i change this
ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine(domain);
to
ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine();
But then i can't manage the permissions IronPython has. Is there a way of doing this differently without serialization, perhaps using reflection? Or is there a better way of sandboxing it(maybe sandbox the whole C# code that manages IronPython)?