Hi All,
I have been using the PythonEngine to host IronPython in my application, it
works great. I have a need to host the PythonEngine in a separate AppDomain and
then provide an API back to the default app domain. I am running into the
black-hole of Security issues. I get the following FileIOPermission
inner-exception during the PythonEngine creation:
at
System.Runtime.CompilerServices.RuntimeHelpers._RunClassConstructor(IntPtr type)
at
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle
type)
at IronPython.Hosting.PythonEngine.Initialize(EngineOptions engineOptions)
in C:\tfs\Fusion\Main\Source\IronPython\IronPython\Hosting\PythonEngine.cs:line
175
at IronPython.Hosting.PythonEngine..ctor(EngineOptions engineOptions) in
C:\tfs\Fusion\Main\Source\IronPython\IronPython\Hosting\PythonEngine.cs:line 141
at ConsoleApplication1.PythonInstance..ctor() in
C:\temp\ConsoleApplication1\Program.cs:line 27
It appears that the PythonEngine is trying to create an assembly file in the
OutputGenerator.cs file. I would like to know the magic to give the separate
AppDomain the ability to write files.
I have also gone as far as configuring the separate AppDomain with special
security permissions, with no impact... that code is also below...
I have trimmed down the application into the following test code:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
using IronPython.Modules;
namespace ConsoleApplication1
{
[Serializable]
public class PythonInstance
{
// IronPython Modules
private static PythonEngine _python;
public PythonInstance()
{
// Create Python Engine
EngineOptions options = new EngineOptions();
options.ExceptionDetail = true;
options.ClrDebuggingEnabled = true;
PythonInstance._python = new PythonEngine(options);
}
public void AddPythonPath(string path)
{
PythonInstance._python.AddToPath(path);
}
}
class Program
{
static void Main(string[] args)
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = Assembly.GetEntryAssembly().FullName;
setup.ApplicationBase =
Path.GetDirectoryName(typeof(Program).Assembly.Location);
AppDomain domain = AppDomain.CreateDomain("PythonDomain", null,
setup);
// Create Test Engine in remote domain
object obj = domain.CreateInstanceAndUnwrap("ConsoleApplication1",
"ConsoleApplication1.PythonInstance");
PythonInstance python = obj as PythonInstance;
python.AddPythonPath(@"C:\temp");
}
}
}
Code to give the app domain special permissions:
private void SetAppDomainPolicy(AppDomain appDomain)
{
// Create an AppDomain policy level.
PolicyLevel pLevel = PolicyLevel.CreateAppDomainLevel();
// The root code group of the policy level combines all
// permissions of its children.
PermissionSet ps = new PermissionSet(PermissionState.Unrestricted);
ps.AddPermission(new
SecurityPermission(SecurityPermissionFlag.AllFlags));
UnionCodeGroup rootCodeGroup =
new UnionCodeGroup(new AllMembershipCondition(),
new PolicyStatement(ps,
PolicyStatementAttribute.Nothing));
NamedPermissionSet localIntranet =
FindNamedPermissionSet("LocalIntranet");
// The following code limits all code on this machine to local
intranet permissions
// when running in this application domain.
UnionCodeGroup virtualIntranet =
new UnionCodeGroup(new
ZoneMembershipCondition(SecurityZone.MyComputer),
new PolicyStatement(localIntranet,
PolicyStatementAttribute.Nothing));
virtualIntranet.Name = "Virtual Intranet";
// Add the code groups to the policy level.
rootCodeGroup.AddChild(virtualIntranet);
pLevel.RootCodeGroup = rootCodeGroup;
appDomain.SetAppDomainPolicy(pLevel);
}
private NamedPermissionSet FindNamedPermissionSet(string name)
{
IEnumerator policyEnumerator = SecurityManager.PolicyHierarchy();
while (policyEnumerator.MoveNext())
{
PolicyLevel currentLevel =
(PolicyLevel)policyEnumerator.Current;
if (currentLevel.Label == "Machine")
{
IList namedPermissions = currentLevel.NamedPermissionSets;
IEnumerator namedPermission =
namedPermissions.GetEnumerator();
while (namedPermission.MoveNext())
{
if (((NamedPermissionSet)namedPermission.Current).Name
== name)
{
return
((NamedPermissionSet)namedPermission.Current);
}
}
}
}
return null;
}
Thanks in advance...
Mike
_______________________________________________
users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com