2011-11-22 17 views
5

Tôi đang cố gắng sử dụng C# làm ngôn ngữ kịch bản sử dụng CSharpCodeProvider (sử dụng VS2010 và .NET 4.0). Tôi muốn các tập lệnh được chạy trong một AppDomain bị giới hạn với các quyền tối thiểu. Hiện tại, tôi nhận được ngoại lệ trong khi cố gắng khởi tạo một lớp trong AppDomain (Gọi tới CreateInstanceAndUnwrap()). Dưới đây là một số mã đơn giản hóa nhằm tái tạo ngoại lệ:SecurityException trong 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");   
     } 
    } 
} 

Trường hợp ngoại lệ được ném từ mscorlib và nó là một System.Reflection.TargetInvocationException có một nội System.Security.SecurityException. Đây là ngoại lệ:

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: 

Vì vậy, có vẻ như tôi rằng mscorlib đòi hỏi sự tin tưởng hoàn toàn. Tôi đã thêm nó như là một hội đồng hoàn toàn đáng tin cậy, nhưng nó không có hiệu lực. Mã ở trên hoạt động nếu tôi đặt quyền không bị giới hạn:

PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted); 

Nhưng tôi muốn hạn chế AppDomain. Tôi làm gì sai ở đây?

Trả lời

2

Xin lỗi vì đã chỉnh sửa muộn. Hãy thử những điều sau đây. Tôi đã nhận nó và chạy trong Visual Studio với một ứng dụng thử nghiệm. Trên một mặt lưu ý, cá nhân tôi không thích "logic" trong các nhà xây dựng vì lỗi thực sự có xu hướng để có được một chút ẩn. Các bước dưới đây có logic biên dịch được chuyển từ hàm tạo sang một phương thức mới.

  1. Đảm bảo ứng dụng Console của bạn có Tên mạnh/Đã ký.
  2. Bao gồm biến sns làm thông số cuối cùng để gọi AppDomain.CreateDomain. Giấy phép LinkDemand yêu cầu ConsoleApp của bạn phải được tin cậy hoàn toàn.

    AppDomain domain = AppDomain.CreateDomain("NewAppDomain", AppDomain.CurrentDomain.Evidence, adSetup, permissions, sns.ToArray()); 
    
  3. Thay đổi tên asmName để sử dụng Đường dẫn tệp đầy đủ cho lắp ráp của bạn.

    String asmName = Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName; 
    
  4. Xóa cuộc gọi CreateInstanceAndUnwrap đến 2 dòng mã sau đây

    var handle = Activator.CreateInstanceFrom(domain, asmName, typeName); 
    var scriptRunner = (ScriptRunner)handle.Unwrap(); 
    
  5. Move tất cả các mã của bạn từ vị thi công đến một phương pháp mới như "Start".

  6. Thêm dòng để gọi phương thức Bắt đầu.

    scriptRunner.Start(); 
    
  7. Thêm FileIOPermission để đọc tệp Danger.cs của bạn.

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

Không, mã hoạt động tốt nếu tôi đặt PermissionSet Unrestricted. Tôi quên đề cập đến điều đó nên tôi đã cập nhật câu hỏi. Vấn đề là vấn đề về quyền bảo mật. Ngoại lệ bảo mật xảy ra đầu tiên trong mscorlib. Khi ngoại lệ tăng lên, nó tạo ra một TargetInvocationException. Nhưng SecurityException là vấn đề thực sự. – Galen

+0

Tôi đã thay đổi câu trả lời dựa trên các chỉnh sửa cho câu hỏi và nhận xét ở trên. – Simon

+0

Nếu tôi thêm phần trên, tôi vẫn nhận được cùng một SecurityException. – Galen

Các vấn đề liên quan