2011-11-22 19 views
5

Próbuję użyć C# jako języka skryptowego przy użyciu CSharpCodeProvider (przy użyciu VS2010 i .NET 4.0). Chcę, aby skrypty działały w ograniczonej domenie AppDomain przy minimalnych uprawnieniach. Obecnie otrzymuję wyjątek podczas próby utworzenia wystąpienia klasy w AppDomain (Wywołanie do CreateInstanceAndUnwrap()). Oto niektóre uproszczone kodu, który odwzorowuje wyjątek:SecurityException w Sandboxed AppDomain

using System; 
using System.Collections.Generic; 
using Microsoft.CSharp; 
using System.CodeDom; 
using System.CodeDom.Compiler; 
using System.Security; 
using System.Security.Policy; 
using System.Security.Permissions; 
using System.Reflection; 
using System.Runtime.Remoting; 

namespace ConsoleApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // set permissions 
      PermissionSet permissions = new PermissionSet(PermissionState.None); 
      permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 

      AppDomainSetup adSetup = new AppDomainSetup(); 
      adSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; 

      //Create a list of fully trusted assemblies 
      Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies(); 
      List<StrongName> sns = new List<StrongName>(); 
      for (int x = 0; x < asms.Length; x++) 
      { 
       StrongName sn = asms[x].Evidence.GetHostEvidence<StrongName>(); 
       if (sn != null && sns.Contains(sn) == false) 
        sns.Add(sn); 
      } 
      //this includes: "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"    

      AppDomain domain = AppDomain.CreateDomain("NewAppDomain", AppDomain.CurrentDomain.Evidence, adSetup, permissions);//, sns);//, sn4, sn, sn2, sn3); 
      try 
      { 
       String asmName = Assembly.GetExecutingAssembly().FullName; 
       String typeName = typeof(ConsoleApp.ScriptRunner).FullName; 
       //Throws exception here 
       ScriptRunner scriptRunner = domain.CreateInstanceAndUnwrap(asmName, typeName) as ScriptRunner; 
      } 
      catch (SecurityException se) 
      { 
       System.Diagnostics.Debug.WriteLine(se.Message); 
      } 
      catch (Exception ex) 
      { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
      } 
     } 
    } 

    public class ScriptRunner : MarshalByRefObject 
    {  
     public ScriptRunner() 
     { 
      //A breakpoint placed here is never reached. 
      CompilerParameters param; 
      param = new CompilerParameters(); 
      param.CompilerOptions = ""; 
      param.GenerateExecutable = false; 
      param.GenerateInMemory = true; 
      param.IncludeDebugInformation = false; 

      // C# compiler 
      CSharpCodeProvider codeProvider = new CSharpCodeProvider(); 

      CompilerResults results = codeProvider.CompileAssemblyFromFile(param, "Danger.cs");   
     } 
    } 
} 

Wyjątkiem jest wyrzucane z mscorlib i jest System.Reflection.TargetInvocationException że ma wewnętrzną System.Security.SecurityException. Oto wyjątek:

System.Reflection.TargetInvocationException was unhandled 
    Message=Exception has been thrown by the target of an invocation. 
    Source=mscorlib 
    StackTrace: 
     at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 
     at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) 
     at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) 
     at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
     at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) 
     at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) 
     at System.Activator.CreateInstance(String assemblyName, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark) 
     at System.Activator.CreateInstance(String assemblyName, String typeName) 
     at System.AppDomain.CreateInstance(String assemblyName, String typeName) 
     at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName) 
     at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName) 
     at ConsoleApp.Program.Main(String[] args) in C:\Documents and Settings\NaultyCS\my documents\visual studio 2010\Projects\ConsoleApplication4\ConsoleApplication4\Program.cs:line 46 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: System.Security.SecurityException 
     Message=Request failed. 
     Source=ConsoleApplication4 
     GrantedSet=<PermissionSet class="System.Security.PermissionSet" 
version="1"> 
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
version="1" 
Flags="Execution"/> 
</PermissionSet> 

     PermissionState=<PermissionSet class="System.Security.PermissionSet" 
version="1" 
Unrestricted="true"/> 

     RefusedSet="" 
     Url=file:///C:/Documents and Settings/NaultyCS/my documents/visual studio 2010/Projects/ConsoleApplication4/ConsoleApplication4/bin/Debug/ConsoleApplication4.EXE 
     StackTrace: 
      at ConsoleApp.ScriptRunner..ctor() 
     InnerException: 

Wygląda na to, że mscorlib domaga się pełnego zaufania. Dodałem go jako całkowicie zaufany zespół, ale nie ma on żadnego efektu. Powyższy kod działa, jeśli ustawię uprawnienia do nieograniczonego:

PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted); 

Ale chcę ograniczyć AppDomain. Co ja tu robię źle?

Odpowiedz

2

Przepraszamy za późną edycję. Spróbuj wykonać następujące czynności. Dostałem go i działa w Visual Studio z aplikacją testową. Na marginesie, ja osobiście nie lubię "logiki" w konstruktorach, ponieważ prawdziwy błąd zazwyczaj jest trochę ukryty. Poniższe kroki mają logikę kompilacji przeniesioną z konstruktora do nowej metody.

  1. Upewnij się, że aplikacja Console ma StrongName/Signed.
  2. Dołącza zmienną sns jako ostatni parametr do wywołania AppDomain.CreateDomain. Zezwolenie LinkDemand wymaga, aby konsola ConsoleApp była w pełni zaufana.

  3. Zmień parametr asmName, aby użyć pełnej ścieżki pliku do swojego zespołu.

    String asmName = Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName; 
    
  4. Usuń połączenie CreateInstanceAndUnwrap następujących 2 linii kodu

    var handle = Activator.CreateInstanceFrom(domain, asmName, typeName); 
    var scriptRunner = (ScriptRunner)handle.Unwrap(); 
    
  5. przenieść wszystkie swoje kod z konstruktora do nowej metody, takie jak „start”.

  6. Dodaj linię, aby wywołać metodę Start.

    scriptRunner.Start(); 
    
  7. Dodaj FileIOPermission czytać plik Danger.cs.

    permissions.AddPermission(new FileIOPermission(PermissionState.None) { AllFiles = FileIOPermissionAccess.Read }); 
    
+0

Nie, kod działa dobrze, jeśli mogę ustawić PermissionSet do nieograniczonego. Zapomniałem o tym wspomnieć, więc zaktualizowałem to pytanie. Problemem jest problem z uprawnieniami zabezpieczeń. Wyjątek bezpieczeństwa dzieje się najpierw w mscorlib. Gdy wyjątek idzie w górę stosu, generuje wyjątek TargetInvocationException. Ale wyjątek SecurityException to prawdziwy problem. – Galen

+0

Zmieniłem odpowiedź na podstawie wprowadzonych zmian na pytanie i komentarz powyżej. – Simon

+0

Jeśli dodaję powyższe, nadal otrzymuję ten sam wyjątek SecurityException. – Galen

Powiązane problemy