2009-08-31 6 views
8

Ich fragte vor einer Weile, wie Plugins Zugriff beschränken (ich möchte verhindern, dass sie auf die Festplatte oder das Netzwerk schreiben), und ich wurde aufgefordert, AppDomain zu verwenden. Ich habe gesucht und versucht und versagt, wie man das funktioniert.Plug-in-Zugriff auf Dateisystem und Netzwerk über App-Domäne beschränken

Kann jemand einige Informationen zur Verfügung stellen, damit ich anfangen kann, einfach setzen Sie eine AppDomain, die nicht erlaubt, in die Datei oder das Netzwerk zu schreiben.

Antwort

5

Ich denke, das ist, was Sie brauchen, wenn ich Ihren Punkt richtig verstehe.

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"); 

Ist das genauer, was du meintest?

Beachten Sie, dass Sie möglicherweise eine Zeichenfolge mit den Pfaden angeben, auf die das Plug-in keinen Zugriff haben soll. Sie können dies angeben, wenn Sie die neue Instanz der FileIOPermission-Klasse initialisieren.

Lassen Sie mich wissen, ob dies hilft. :-)

+0

Das scheint genau zu sein, was ich nach, ich bekomme Der angegebene Assembly Name oder Codebase war ungültig. (Ausnahme von HRESULT: 0x80131047) jetzt, aber ich hatte noch nicht die Zeit, um mehr darüber zu schauen (Improberly etwas falsch zu machen). Ich bekomme morgen mehr Zeit und lass es dich wissen – EKS

+0

Also, war das was du gesucht hast? Ich schätze, da du es anscheinend überprüft hast. :-) –

+0

@EKS müssen Sie aus dem gleichen Ordner oder einem der untergeordneten Ordner des Ordners laden. –

0

Wenn Sie Plugins verwenden, könnten Sie vielleicht über Proxies wissen.

Während Sie Ihre Assembly über einen Proxy laden, können Sie die Sicherheitsrichtlinienebene für diese bestimmte Assembly über die LoadAssembly() - Methode angeben, wenn ich mich richtig erinnere. Mit anderen Worten, dies geschieht durch Reflexion.

Ich weiß, dass meine Antwort nicht so detailliert ist, aber ich hoffe, es wird Ihnen eine Vorstellung davon geben, wo Sie nach Ihrer Lösung suchen sollten. Ich werde nach weiteren Einzelheiten suchen, damit ich besser helfen kann. =)

Ich hoffe, Sie werden Ihre Ergebnisse teilen, wenn Sie es getan haben.

15

Für .net Framework 4.0, folgen Sie bitte dem folgenden Code von this MSDN Artikel.

Das folgende Beispiel implementiert die Prozedur im vorherigen Abschnitt. In diesem Beispiel enthält ein Projekt namens Sandboxer in einer Visual Studio-Projektmappe auch ein Projekt namens UntrustedCode, das die Klasse UntrustedClass implementiert. In diesem Szenario wird davon ausgegangen, dass Sie eine Bibliotheksassembly heruntergeladen haben, die eine Methode enthält, von der erwartet wird, dass sie wahr oder falsch zurückgibt, um anzugeben, ob es sich bei der von Ihnen angegebenen Nummer um eine Fibonacci-Nummer handelt. Stattdessen versucht die Methode, eine Datei von Ihrem Computer zu lesen. Das folgende Beispiel zeigt den nicht vertrauenswürdigen Code.

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; 
     } 
    } 
} 

Das folgende Beispiel zeigt den Sandboxer-Anwendungscode, der den nicht vertrauenswürdigen Code ausführt.

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(); 
     } 
    } 
} 
Verwandte Themen