El blog del burgués

14 abril 2010

Marcado de privilegios con un manifiesto

Filed under: C# — elburgues @ 6:59 AM

Recientemente me he topado con un problema y me ha parecido interesante publicar cómo se ha resuelto. Se trataba de probar el comportamiento bajo windows 7 de una aplicación .NET desarrollada bajo windows xp. La aplicación en cuestión accede al registro de windows para escribir un valor en una clave. Ahí es dónde surgió el problema, en la sentencia OpenSubKey, la cual, bajo windows xp cumplía sin problema alguno su labor, sin embargo, bajo windows 7 se lanzaba la siguiente excepción: 

System.Security.SecurityException: Requested registry access is not allowed.
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)…
   

En windows XP los administradores no tienen ningún problema para ejecutar un instalador, modificar el registro, o crear carpetas en las areas protegidas por el sistema, pero en windows 7, un administrador no tiene el acceso total. Sin embargo, es posible establecer los privilegios de una aplicacion desde su ensamblado para que ésta exija estos privilegios al sistema al ejecutarse, marcando privilegios en el manifiesto de la aplicación. Cuando se crea un nuevo proceso, el servicio de información de aplicaciones (AIS) inspecciona el manifiesto de la aplicación que está incrustado en los recursos de la aplicación. Esto prevalece sobre cualquier otro tipo de marcado de aplicaciones, incluido el marcado de compatibilidad de una aplicación o la detección del instalador de UAC (User Access Control). El manifiesto define un nivel de ejecución que indica a Windows los privilegios necesarios para ejecutar el archivo binario. El marcado del manifiesto de aplicación es relevante sólo para archivos EXE, no DLL, UAC no inspecciona archivos DLL durante la creación del proceso.  

Las tres posibilidades de nivel de ejecución son:    

  1. asInvoker: la aplicacion obtiene los privilegios de aquel usuario o proceso que lo ejecutó (esta configuracion es la que se establece por defecto en cualquier proyecto nuevo).
  2. highestAvailable: la aplicacion exije los privilegios mas altos posibles de acuerdo al usuario que ejecutó el programa.
  3. requireAdministrator: establece que el proceso se debe crear con un token de usuario que sea miembro del grupo administradores. Si el usuario que intentó crear este proceso no es administrador, se mostrará un cuadro de diálogo para que proporcione sus credenciales.

Por ejemplo, con Visual Studio 2008, podemos añadir un nuevo archivo de manifiesto a una aplicación windows form recién creada:   

 

En las propiedades de la aplicación, seleccionamos cual es el manifiesto que queremos incrustar:   

 

Ahora solo nos queda establecer en el manifiesto, el nivel de ejecución que nos interesa. Haciendo doble click sobre él, nos aparece en el editor el contenido del manifiesto:   

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
            If you want to change the Windows User Account Control level replace the
            requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            If you want to utilize File and Registry Virtualization for backward
            compatibility then delete the requestedExecutionLevel node.
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>

Cambiamos level=”asInvoker” por level=”requireAdministrator”, guardamos los cambios, recompilamos la aplicación y listo, problema resuelto.

Anuncios

5 comentarios »

  1. Menos mal que no lo titulaste como “Manifiesto de marcados privilegios”, porque viniendo de todo un burgués sería para considerarlo como una declaración de intenciones. 😉

    Como siempre, muy didáctico. ¿Pero para cuando más Astronomía? 🙂 🙂

    Un saludo.

    Comentario por Trotalomas — 16 abril 2010 @ 10:20 AM | Responder

    • Pues, la verdad, no eres el único que me está diciendo que escriba de ese tema. Tengo pendiente en mi cabeza desde hace tiempo hablar del efecto fotoeléctrico. Espero lanzarlo este fin de semana, os lo debo, fieles lectores… 🙂

      Comentario por elburgues — 16 abril 2010 @ 10:59 AM | Responder

  2. Saludos amigo Burgues, me parece muy interesante tu explicación, tengo una pregunta, el archivo .manifiest se lo puede agregar al \DirApp\MiAplicacion.exe.manifiest , para cualquier programa o solamente los compilados de VS 2008 y superiores muchas gracias por tu aclaración.

    Comentario por Juan Carlos — 7 febrero 2011 @ 10:37 PM | Responder

    • Saludos Juan Carlos, muchas gracias por tu comentario.

      Todo ensamblado contiene un manifiesto, que son metadatos con información sobre las características del ensamblado. Este manifiesto puede almacenarse en cualquiera de los módulos que formen el ensamblado o en uno específicamente creado para ello, siendo lo último necesario cuando sólo contiene recursos (ensamblado satélite).

      ¡saludos!

      Comentario por elburgues — 9 febrero 2011 @ 1:37 PM | Responder

  3. hola que tal, oye una duda.

    Estoy intentando agregar una .dll en tiempo de ejecucuòn en una aplicación en .NET, pero al momento de intentar agregarla me manda el mensaje “Se esperaba que el módulo tuviera un manifiesto de ensamblado. (Excepción de HRESULT: 0x80131018)”, menciono que la dll es foranea, pero yo la requiero por los controles que peuda extaer de esa .dll

    Hay forma de integrarle dicho manifiesto? o como puedo agregar mi .dll a mi aplicación.

    De antemano muchas Gracias

    Saludos !!!!!!!!!!

    Blanca

    Comentario por Blanca — 14 junio 2011 @ 1:48 AM | Responder


RSS feed for comments on this post.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Crea un blog o un sitio web gratuitos con WordPress.com.

A %d blogueros les gusta esto: