2009-08-31 10 views
8

Hace un tiempo pregunté cómo restringir el acceso a los complementos (quiero evitar que escriban en el disco o la red) y me dijeron que use AppDomain. He buscado, intenté y fallé sobre cómo hacerlo funcionar.Restringir el acceso de los complementos al sistema de archivos y a la red a través del dominio de aplicación

¿Alguien puede proporcionar alguna información para que pueda comenzar, simplemente haga un dominio de la aplicación que no permite escribir en el archivo o la red.

Respuesta

5

Supongo que esto es lo que necesita, si entiendo correctamente su 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"); 

¿Es esto más exactamente lo que usted quiso decir?

Observe que puede proporcionar una matriz de cadenas que contiene las rutas en las que no desea que tenga acceso el complemento. Puede proporcionar si al inicializar la nueva instancia de la clase FileIOPermission.

Avísame si esto ayuda. :-)

+0

Eso parece ser exactamente lo que estoy buscando, obtengo El nombre del ensamblado o la base de código dados no son válidos. (Excepción de HRESULT: 0x80131047) ahora, pero aún no he tenido tiempo de investigar más (estoy haciendo algo incorrectamente). Tendré más tiempo mañana y le dejaré saber – EKS

+0

Entonces, finalmente, ¿era esto lo que estaba buscando? Supongo, ya que parece que lo has comprobado. :-) –

+0

@EKS tiene que cargar desde la misma carpeta o uno de los elementos secundarios de la carpeta. –

0

Si está utilizando complementos, tal vez sepa acerca de los proxys.

Al cargar su ensamblado a través de un proxy, puede especificar el nivel de política de seguridad para este ensamblado en particular a través del método LoadAssembly(), si recuerdo correctamente. En otras palabras, esto se hace a través de la reflexión.

Sé que mi respuesta no es muy detallada, pero espero que le dé una idea de dónde buscar su solución. Voy a echar un vistazo para encontrar más detalles sobre el tema para que pueda ser de mejor ayuda. =)

Espero que compartas tus hallazgos cuando lo hayas hecho.

15

Para .NET Framework 4.0, por favor, siga el siguiente código desde this artículo de MSDN.

El siguiente ejemplo implementa el procedimiento en la sección anterior. En el ejemplo, un proyecto llamado Sandboxer en una solución de Visual Studio también contiene un proyecto llamado UntrustedCode, que implementa la clase UntrustedClass. Este escenario asume que ha descargado un conjunto de biblioteca que contiene un método que se espera que devuelva verdadero o falso para indicar si el número que proporcionó es un número de Fibonacci. En cambio, el método intenta leer un archivo de su computadora. El siguiente ejemplo muestra el código que no es de confianza.

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

El siguiente ejemplo muestra el código de la aplicación Sandboxer que ejecuta el código que no es de confianza.

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(); 
     } 
    } 
} 
Cuestiones relacionadas