2009-08-31 12 views
8

Ho chiesto qualche tempo fa come limitare l'accesso ai plug-in (voglio impedire loro di scrivere sul disco o sulla rete) e mi è stato detto di usare AppDomain. Ho cercato e provato e ho fallito su come farlo funzionare.Limita l'accesso del plug-in al file system e alla rete tramite appdomain

Qualcuno può fornire alcune informazioni così posso iniziare, semplicemente mettere un AppDomain che non consente di scrivere sul file o sulla rete.

risposta

5

credo che questo è quello che vi serve, se ho capito bene il tuo punto.

System.Security.PermissionSet ps = 
    new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None); 
ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.NoAccess, "C:\\")); 
System.Security.Policy.PolicyLevel pl = System.Security.Policy.PolicyLevel.CreateAppDomainLevel(); 
pl.RootCodeGroup.PolicyStatement = new System.Security.Policy.PolicyStatement(ps); 
AppDomain.CurrentDomain.SetAppDomainPolicy(pl); 
System.Reflection.Assembly myPluginAssembly = AppDomain.CurrentDomain.Load("MyPluginAssembly"); 

È più esattamente ciò che intendevi?

Si noti che l'utente possa fornire una serie di stringhe containg i percorsi in cui non si vuole il plugin per avere accesso. È possibile fornire se durante l'inizializzazione della nuova istanza della classe FileIOPermission.

Fatemi sapere se questo aiuta. :-)

+0

Questo sembra essere esattamente quello che ho dopo, ottengo Il nome dell'assembly o codice fornito non è valido. (Eccezione da HRESULT: 0x80131047) ora ma non ho ancora avuto il tempo di approfondire la questione (sto facendo in modo proberto qualcosa di sbagliato). Domani ho più tempo e ti faccio sapere – EKS

+0

Quindi, finalmente, era questo quello che stavi cercando? Immagino, dal momento che sembra che tu abbia controllato. :-) –

+0

@EKS devi caricare dalla stessa cartella o uno dei figli della cartella. –

0

Se stai usando i plugin, si potrebbe forse sapere su proxy.

Durante il caricamento dell'assieme tramite un proxy, è possibile specificare il livello di politica di sicurezza per questo particolare assieme tramite il metodo LoadAssembly() o così, se non ricordo male. In altre parole, ciò avviene attraverso la riflessione.

Conosco la mia risposta non è molto dettagliata, ma spero che vi darà un'idea di dove andare a cercare per la vostra soluzione. Prenderò un occhio per trovare ulteriori dettagli sull'argomento in modo che possa essere di maggiore aiuto. =)

auguriamo che condividere le tue scoperte quando hai fatto.

15

Per .net framework 4.0, si prega di seguire il codice seguente da this articolo MSDN.

L'esempio seguente implementa la procedura nella sezione precedente. Nell'esempio, un progetto chiamato Sandboxer in una soluzione di Visual Studio contiene anche un progetto denominato UntrustedCode, che implementa la classe UntrustedClass. In questo scenario si presuppone che sia stato scaricato un assembly di libreria contenente un metodo che si prevede restituisca true o false per indicare se il numero fornito è un numero di Fibonacci. Invece, il metodo tenta di leggere un file dal tuo computer. L'esempio seguente mostra il codice non affidabile.

using System; 
using System.IO; 
namespace UntrustedCode 
{ 
    public class UntrustedClass 
    { 
     // Pretend to be a method checking if a number is a Fibonacci 
     // but which actually attempts to read a file. 
     public static bool IsFibonacci(int number) 
     { 
      File.ReadAllText("C:\\Temp\\file.txt"); 
      return false; 
     } 
    } 
} 

L'esempio seguente mostra il codice dell'applicazione Sandboxer che esegue il codice non attendibile.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Security; 
using System.Security.Policy; 
using System.Security.Permissions; 
using System.Reflection; 
using System.Runtime.Remoting; 

//The Sandboxer class needs to derive from MarshalByRefObject so that we can create it in another 
// AppDomain and refer to it from the default AppDomain. 
class Sandboxer : MarshalByRefObject 
{ 
    const string pathToUntrusted = @"..\..\..\UntrustedCode\bin\Debug"; 
    const string untrustedAssembly = "UntrustedCode"; 
    const string untrustedClass = "UntrustedCode.UntrustedClass"; 
    const string entryPoint = "IsFibonacci"; 
    private static Object[] parameters = { 45 }; 
    static void Main() 
    { 
     //Setting the AppDomainSetup. It is very important to set the ApplicationBase to a folder 
     //other than the one in which the sandboxer resides. 
     AppDomainSetup adSetup = new AppDomainSetup(); 
     adSetup.ApplicationBase = Path.GetFullPath(pathToUntrusted); 

     //Setting the permissions for the AppDomain. We give the permission to execute and to 
     //read/discover the location where the untrusted code is loaded. 
     PermissionSet permSet = new PermissionSet(PermissionState.None); 
     permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 

     //We want the sandboxer assembly's strong name, so that we can add it to the full trust list. 
     StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>(); 

     //Now we have everything we need to create the AppDomain, so let's create it. 
     AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly); 

     //Use CreateInstanceFrom to load an instance of the Sandboxer class into the 
     //new AppDomain. 
     ObjectHandle handle = Activator.CreateInstanceFrom(
      newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName, 
      typeof(Sandboxer).FullName 
      ); 
     //Unwrap the new domain instance into a reference in this domain and use it to execute the 
     //untrusted code. 
     Sandboxer newDomainInstance = (Sandboxer) handle.Unwrap(); 
     newDomainInstance.ExecuteUntrustedCode(untrustedAssembly, untrustedClass, entryPoint, parameters); 
    } 
    public void ExecuteUntrustedCode(string assemblyName, string typeName, string entryPoint, Object[] parameters) 
    { 
     //Load the MethodInfo for a method in the new Assembly. This might be a method you know, or 
     //you can use Assembly.EntryPoint to get to the main function in an executable. 
     MethodInfo target = Assembly.Load(assemblyName).GetType(typeName).GetMethod(entryPoint); 
     try 
     { 
      //Now invoke the method. 
      bool retVal = (bool)target.Invoke(null, parameters); 
     } 
     catch (Exception ex) 
     { 
      // When we print informations from a SecurityException extra information can be printed if we are 
      //calling it with a full-trust stack. 
      (new PermissionSet(PermissionState.Unrestricted)).Assert(); 
      Console.WriteLine("SecurityException caught:\n{0}", ex.ToString()); 
      CodeAccessPermission.RevertAssert(); 
      Console.ReadLine(); 
     } 
    } 
} 
Problemi correlati