Surviving the Night

El blog de Pablo Doval sobre .NET, SQL, WinDbg...

November 2006 - Artículos

Monkey Business: Mono en un Virtual PC

Esta semana he estado en La Coruña dando un curso de Introducción a C# y la Plataforma .NET para algunos alumnos de la UDC y la verdad es que fue muy entretenido, me lo pasé como un enano y creo que los chicos también. A parte de la teoría de siempre sobre la plataforma y la sintaxis del lenguaje traté, como siempre, de dar un valor añadido; al fin y al cabo, limitarnos a leer las presentaciones y hacer cuatro demos me parece inútil en la mayoría de los casos. Mi audiencia de esta semana, por ejemplo, se encuentra inmersa en la temporada de exámenes parciales, por lo que muchos de ellos no podrán llegar a casa y ponerse a repetir lo que hicimos en el curso y profundizar en ello. Sin duda, toda la sintaxis y las demos que hayamos hecho se les olvidará, cosa que por otra parte me importa más bien poco, para algo tienen google, la MSDN y 32768 recursos adicionales en la red.

Lo que me interesa realmente es emocionarles, explicarles que puede hacer la tecnología por nosotros, que novedades aporta, y sobre todo, escenarios y casos de uso... en fin, que me pase el curso entero contando batallitas :_)  Estas batallitas, consejos desde las trincheras o como queráis llamarlo es lo que le da un valor añadido a una presentación o un curso. Los alumnos agradecen que nos pongamos en su entorno (como puede ayudarles .NET con su proyecto de Fin de Carrera, como se relacionan las clases de colecciones con lo que han estudiado en Estructuras de Datos, etc...) y que también les demos un pequeño avance de lo que podrán ver en las empresas en la vida real.

Con la tontería de las batallitas y del valor añadido, acabamos hablando y haciendo demos del recolector de basura, de los profilers (F1 y CLRProfiler principalmente), sandcastle, NUnit, FxCop y, como no, Mono. Así, hoy viernes compilamos bajo Mono algo de código que habíamos hecho el día anterior en Visual Studio .NET, y lo hicimos todo dentro de una máquina virtual con Monoppix en un Virtual PC.

Para quienes no lo conozcáis, Monoppix es un distribución Live CD de Linux (¡quizá deba decir GNU/Linux para que Kilian y sus acólitos me perdonen la vida! XD) basada en la popular Knoppix, lo que quiere decir que no necesitamos instalarla en nuestro disco duro, ya que se distribuye como un CD auto-arranque el cual, tras su carga, descomprime en memoria sus contenidos para poder usarlo como si estuviera desplegado en nuestro disco duro. La imagen de CD ocupa menos de 500 Mb y podéis descargarla libremente de internet (www.monoppix.com).

Como el uso de Mono en este taller iba a ser mínimo, y no me agradaba la idea de andar reiniciando para pasar de Mono a Vista, decidí probar a ver qué tal iba en una máquina virtual con Virtual PC. Para ello seguí los siguientes pasos:

  • Creé una máquina nueva con la siguiente configuración:
    • 512 Mb de Ram
    • Sin disco duro (inicialmente, luego podemos crear uno chiquito para el archivo de swap)
  • Agregué como unidad de CD la imagen .iso del CD de monoppix.

Arranqué la máquina virtual, y en pocos segundos la consola me saludo con el clásico "boot:". No tenía pensado pasarle ninguna opción al kernel, así que pulse enter y al minuto escaso tenía delante un escritorio KDE (mmm... molaba más con Gnome (1)) totalmente funcional, con Mono integrado y las herramientas básicas instaladas, como MonoDevelop (que aún así no pude aprovechar mucho, pues la interfaz de usuario se ve francamente mal en mi VPC). Grabé el estado de la máquina virtual después de la configuración básica del Knoppix y... Ta-Dah!!! Ya tenía mi máquina virtual con Mono en unos 500Mb, que pienso dejar por el disco duro del portátil para tener a mano; seguro que será muy socorrida para las típicas preguntas de los hijos de Stallman en más de una charla :)

En fin, el juguete está muy bien si queréis jugar y conocer lo que hay al otro lado del infierno :) Es súper fácil montarlo como máquina virtual, ocupa muy poco, y para alguna demo está muy apañado. Just my ((double)2 / (double)100) cents.

 (1): Oh!! Dios!!! ¿Realmente he dicho eso? Primero Mono, después Gnome... ¿Acabaré poniendo un altar a Miguel de Icaza en mi casa y rindiéndole culto todas las noches? Brrrrrrr... escalofríos me dan, oye...

Paranoid: Cifrado de Datos en SQL Server 2005

Los DBAs son criaturas paranoicas. No, en serio, los amo de corazón, pero son la cosa más desconfiada que hay en el mundo; y si no lo es el DBA, lo será su jefe, o el jefe de su jefe, o alguien en su línea de reporte directo que considera que la seguridad de su empresa (ya sea ésta un Banco internacional o la Agrupación de Tamborileros y Triangulistas Amateur de Cerecinos de Campo) es crítica y de mayor importancia. Qué curioso, sobre todo si tenemos en cuenta su reticencia innata para actualizar de nivel de Service Pack, o para tener una cuidadosa política de permisos en el servidor que minimicen los riesgos de los ataques de inyección SQL, que no nos engañemos, si bien la vulnerabilidad de una inyección SQL la pone en bandeja el desarrollador, su explotabilidad viene determinada por la configuración y administración de la misma. Aquí estamos todos en el mismo barco, o como diría el gran Fran Peula, "Aquí, o f******* todos o la p*** al rio" :)).

Hoy he tenido un momento flashback. Como algunos de vosotros sabéis, hasta hace poco trabajaba en Microsoft dando soporte a SQL Server, y hoy me he acordado de dos clientes en particular. Uno de ellos, un chico gallego muy majo, de una empresa de desarrollo de La Coruña, que llamo a soporte de Microsoft porque habían sufrido una corrupción en uno de sus archivos de datos y era un tema crítico para ellos. La verdad es que trabajamos muy bien en ese caso; esfuerzos por los dos lados, nos quedamos bastante más tarde del horario establecido, y además hubo mucha suerte porque se pudo recuperar lo que necesitaban. Al final de la llamada, tras la recuperación de los datos, pude oír como pocas veces risas de satisfacción de éste chico y sus compañeros, se les notaba el tremendo alivio en todas las palabras de agradecimiento (realmente esa parte del trabajo era impagable... :_) ) y ¡¡¡hasta su compañero 'linuxero' alabó el producto y la calidad del soporte!!! ¿Creéis que me he acordado de él por todo esto? Pues no, me acordé de él porque tenía hambre, estoy en La Coruña y me prometió una mariscada xDDD Realmente no es el momento, porque no tengo casi nada de tiempo libre, pero la próxima vez que venga le llamaré; yo pondré las cervezas.

El otro cliente si tiene que ver con la parrafada inicial. Se trata de un chico de UK, un tal Greg, que estaba planeando el despliegue de una nueva aplicación, destinada a ser usada con SQL Server 2005, y que iba a contener información muy sensible. Lo que éste chico me preguntaba era básicamente si se podían cifrar los datos de una columna de SQL Server de tal modo que solo un usuario especial pudiera acceder a ellos, impidiendo el acceso a todos los demás usuarios, incluidos los sysadmin. Lo recordaré siempre porque fue mi primer caso con SQL Server 2005... ¿Veis? En el fondo soy un romanticón :)

Como me parece un tema interesante me gustaría compartir con vosotros una versión light del resumen que le hice, que a su vez estaba basada en dos geniales artículos de la MSDN, ya que estoy seguro que muchos de vosotros lo encontrareis útil tanto a nivel de desarrollo como de consultoría, etc. 

Cifrado de Datos en SQL Server Dosmilcinc... Yukon

Como suele suceder, escoger el nivel de protección adecuado consiste en buscar el balance entre la seguridad y la usabilidad (en el sentido de lo que se complique el empleo y administración de la base de datos). Para tomar esta decisión, primeramente debemos determinar de quien queremos proteger nuestros datos. Para ello vamos a considerar tres niveles de protección básicos:

  • Nivel 2: Protección frente a atacantes que pueden acceder a los ficheros físicos de la base de datos.
  • Nivel 1: Nivel 2 + protección frente al Sysadmin
  • Nivel 0: Nivel 1 + protección frente al propietario de la base de datos (dbo)

Ahora voy a proceder a explicar la aproximación que deberíamos tomar para securizar nuestros datos sensibles en cada uno de esos niveles, desde el más seguro (Nivel 0) hasta el menos seguro, pero más usable (Nivel 2).

Todos estos niveles se basan en el hecho de que los datos sean protegidos por una clave simétrica, ya que es la manera más eficiente de cifrar los datos, pero emplean diferentes mecanismos para proteger ésta clave simétrica. A partir de aquí surgen las diferencias:

            Nivel 0: Solo el usuario autorizado puede ver sus datos

Para lograr este grado de protección de nuestros datos, la clave simétrica debe ser protegida por una clave que solo será conocida por el usuario que ha cifrado los datos. Éste es el modo más seguro, ya que no hay manera en la cual el propietario de la base de datos, o el sysadmin, puedan acceder a la clave simétrica, ya que ésta no está almacenada en el servidor.

Los ficheros de datos se aseguran de este modo también, ya que aún en el supuesto de que un atacante consiga obtener acceso a los ficheros y adjuntarlos a su servidor, no podrá acceder a las columnas cifradas mientras no tenga a su disposición la contraseña de cifrado de la clave simétrica.

Evidentemente, hay una seria contrapartida en términos de usabilidad: para acceder a estos datos, necesitamos asegurarnos de que la clave sea abierta, y para ello debemos suministrar explícitamente la clave con la que se cifró la clave simétrica.

Podemos comprobar en cualquier momento las claves abiertas en una sesión dada simplemente echándole un vistazo a la vista de administración del sistema sys.open_keys. Si la clave no estuviera abierta, entonces la siguiente sentencia DDL sería necesaria para abrirla:

OPEN SYMMETRIC KEY <nombre_clave> DECRYPTION BY PASSWORD = ‘<contraseña>’

            Nivel 1: Otorgándole acceso al DBO

En éste escenario suponemos que el propietario de la base de datos es de fiar y puede tener acceso a las columnas sensibles, de modo que nos podemos permitir relajar un poco las restricciones de seguridad; lo que haremos en este caso es proteger la clave simétrica con un certificado (o una clave asimétrica). La clave privada del certificado (o de la clave asimétrica) necesita ser protegida por la Database Master Key o llave maestra de la base de datos. Para lograr esto en el momento de creación del certificado, debemos simplemente omitir la opción ENCRYPTION BY PASSWORD:

CREATE CERTIFICATE cert WITH SUBJECT = ‘EncryptionCert’

Si ya disponemos de un certificado existente (o clave asimétrica) protegido por una contraseña, y queremos que la protección la realice la Database Master Key, deberemos alterar éste certificado. Me gustaría recalcar aquí que la sintaxis para esta labor puede parecer muy poco intuitiva, así que como siempre, en caso de duda deberemos recurrir a los Books On Line del producto.

ALTER CERTIFICATE cert WITH PRIVATE KEY DECRYPTION BY PASSWORD = ‘<password>’

Y aquí viene la parte importante, el momento donde realmente protegemos los datos del sysadmin. El usuario dbo, o el usuario con privilegios, debe asegurarse de que la Database Master Key esté protegida solo mediante una contraseña. En el momento de creación de ésta Database Master Key se establece que, por defecto, sea cifrada por la Service Master Key, de modo que debemos eliminar ésta protección con una sentencia DROP como la siguiente:

ALTER MASTER KEY DROP ENCRYPTION BY SERVICE MASTER KEY

De éste modo, el propietario de la base de datos tiene acceso a los datos del usuario privilegiado, ya que puede usar la Database Master Key para descifrar la clave privada en el certificado, de modo que pueda ser luego usada para abrir la clave simétrica y descifrar los datos protegidos. No obstante, estamos protegidos del sysadmin ya que no será capaz de abrir la Database Master Key sin la clave apropiada.

            Nivel 2: Otorgándole al Sysadmin acceso a los datos

En éste escenario vamos a confiar también en el usuario sysadmin; solo nos preocupa la posibilidad de que nuestros datos sean robados y queremos prevenir que los atacantes puedan acceder a los datos sensibles en caso de que se hagan con el fichero de datos y puedan adjuntarlo a su base de datos. 

Debemos cifrar los datos con una clave simétrica, y proteger ésta clave simétrica con un certificado (o clave asimétrica) tal y como vimos en el nivel 1 de protección. Éste ultimo certificado es protegido, como demostramos antes, por la Database Master Key.

La diferencia importante es que el propietario de la base de datos NO debería hacer un drop del cifrado de la Database Master Key por la Service Master Key. Es decir, debemos dejarlo tal como se crea por defecto, o bien, en caso de que haya sido modificado, volver a establecerla con la siguiente sentencia DDL:

ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY

El sysadmin, de éste modo, tendrá acceso a la Database Master Key y por tanto, a cualquier objeto cifrado por la misma. Esto, evidentemente, implica que los datos no están protegidos ni frente al propietario de la base de datos ni frente al administrador del sistema, pero hemos conseguido que los datos estén protegidos en el fichero de datos. De este modo, si alguien robara los ficheros de la base de datos y fuera capaz de adjuntarlos a su propio SQL Server, no sería capaz de leer los datos cifrados ya que no tiene acceso a la contraseña que cifra la clave simétrica, ni acceso a ninguna de las claves de la jerarquía que protege la clave simétrica.

En resumen, el empleo de la jerarquía de claves en SQL Server 2005 facilita las áreas administrativas y de programación ya que no necesitamos abrir explícitamente las claves usadas para proteger los datos. No obstante, si queremos una securización adicional de los datos, debemos escoger la altura en la jerarquía a partir de la cual queremos cifrar la clave con una clave simétrica. Esto nos permite aumentar dramáticamente la seguridad, a costa, como ya vengo comentandoos, de una mayor complejidad administrativa debido al hecho de tener que abrir y cerrar las claves manualmente.

Desde un punto de vista del rendimiento, es evidente que se producirá una sobrecarga en el sistema. No obstante, no podemos estimarla a priori, ya que depende inmensamente del algoritmo de cifrado empleado, así como de la cantidad de los datos.

Ejemplo

Os dejo aquí un ejemplillo que muestra algunos de los conceptos que os comenté en el breve artículo. Es un script SQL para ir ejecutando pasito a pasito, leyendo los comentarios. Espero que el cacharro este lo formatee medio bien.

CREATE DATABASE PruebaBaseDatosSegura

GO

USE PruebaBaseDatosSegura

-- Creamos una nueva tabla donde vamos a almacenar el nombre del empleado (no
-- cifrado) y el numero de la seguridad social del mismo. Vamos a cifrar el número de
-- la seguridad social durante la inserción, de modo que tenemos que tener esto en
-- mente cuando establezcamos el tipo de datos, que deberá ser un varbinary de
-- modo que pueda contener la cadena resultante por el algoritmo de cifrado.

CREATE TABLE empleados (emp_nombre varchar(50), nss varbinary(256) primary key clustered)

-- Ahora creamos la clave simétrica que vamos a usar para cifrar/descifrar los datos

CREATE SYMMETRIC KEY skey WITH ALGORITHM = triple_des ENCRYPTION BY PASSWORD = 'C1av3'

-- Ahora un fragmento interesante... debemos tener en mente que si queremos usar
-- una clave, debemos abrirla primero. Para abrir una clave debemos usar la sentencia
-- OPEN. La clave podría estar protegida por un certificado, por la “Service Master Key”,
-- por la “Database Master Key” o por una contraseña. En éste ejemplo, y para hacerlo
-- coincidir con el escenario en el cual queremos evitar que el propietario de la base de
-- datos y el sysadmin puedan acceder a los datos, debemos suministrar la contraseña
-- en la sentencia open.

OPEN SYMMETRIC KEY skey DECRYPTION BY PASSWORD = 'C1av3'

-- Vamos a insertar ahora algunos valores, usando la función encryptbykey() para generar
-- un stream cifrado de la cadena que le pasamos como parámetro.

INSERT INTO empleados values ('Tom', encryptbykey(key_guid('skey'), '111-11-1111'))
INSERT INTO empleados values ('John', encryptbykey(key_guid('skey'), '222-22-2222'))
INSERT INTO empleados values ('Bob', encryptbykey(key_guid('skey'), '333-33-3333'))

-- Si ahora hacemos la select, podemos ver que el campo nss contiene solo un stream de
-- bytes ilegible.

SELECT * FROM empleados

-- Para poder leer los datos, necesitamos convertir desde el varbinary donde almacenamos
-- los datos, al tipo de datos de destino deseado, en este caso, varchar.

SELECT CONVERT(varchar(256), decryptbykey(nss)) FROM empleados

-- En el SSMS, usamos Ctrl-L o desde el menu: Query\Display Estimated Execution Plan,
-- para comprobar el plan de ejecución estimado. Podemos ver que se realiza un descifrado
-- por cada fila escaneada.

SELECT CONVERT(varchar(256), decryptbykey(nss)) FROM empleados WHERE CONVERT(varchar(256), decryptbykey(ssn) ) = '111-11-1111'

-- ... a ver que pasa con la clave cerrada...

CLOSE SYMMETRIC KEY skey
GO
SELECT CONVERT(varchar(256), decryptbykey(nss)) FROM empleados

-- Limpieza final... Ahora borramos la base de datos de ejemplo

USE Master
DROP DATABASE PruebaBaseDatosSegura

Como se puede ver en el ejemplo, cada vez que queremos acceder a un campo cifrado debemos descifrarlo con una función, y después hacer un cast al tipo de datos deseado. Esto tiene un impacto sobre el rendimiento de la aplicación, pero es algo que deberíamos medir y probar en nuestros sistemas.

Respecto a los aspectos de seguridad, obviamente esta implementación es mucho más robusta de lo que nunca haya sido SQL Server 2000, pero eso no quiere decir que podamos descansar tranquilos simplemente por utilizar las características criptográficas del producto. Hay otros modos de atacar los datos; por ejemplo, si el administrador de la base de datos quisiera acceder a los mismos de modo no autorizado y fuera suficientemente hábil, podría recurrir a múltiples trucos para obtener los datos; desde sniffers para capturar contraseñas a ataques de fuerza bruta, pasando por el empleo malintencionado de un depurador sobre el producto.

Con esto quiero haceros consciente de que la seguridad no es solo un asunto de cómo almacenemos los datos; todos los detalles del entorno juegan su papel. Desde la configuración de permisos de Windows, al almacenamiento físico de los datos, todo ha de ser tenido en cuenta.

Ya terminoooo...

Me gustaría terminar con una reflexión que le hacía a Greg cuando estaba decidiendo su implementación final: a simple vista parece que la opción de cifrar con una clave que no se almacene en el SQL Server y solo conozca una persona parece la más segura, pero como un día el propietario de esta clave sea atropellado por el camión de los pollos(tm), abducido por los Vogones, o se vaya a cenar al Restaurante del Fin del Mundo nos podemos olvidar de todos los datos que estuvieran cifrados con su clave. Así de crudo.

Speed of Light: ¿Usa el DataReader cursores?

Hace unos días tuve una agradable conversación con unos compañeros que nos acabó llevando al espinoso asunto del uso de los cursores... momento en el cual este tipo de conversaciones suelen dejar de ser tan agradables y pasan a la categoría de Guerras de Religión (ya sabéis, cursores siempre vs. cursores nunca, vi vs. emacs, Windows vs. GNU/Linux y como no, el rey de las guerras de religión... Aritos de Cebolla vs. Fingers de Mozarella).

El caso es que yo, habiendo entrado en modo talibán durante el ejercicio de mis labores como detractor del empleo de los cursores, estaba defendiendo que no era la mejor de las ideas utilizar cursores para un proceso que podría trabajar potencialmente con millones de filas. Me quedé sorprendido cuando otro chico me comentó que los DataReaders de .NET estaban implementados mediante cursores, y ciertamente recordaba haber leído algo similar durante mi formación en ADO.NET, por lo que volví a la documentación de la MSDN y pudimos comprobar cómo los DataReaders funcionan mediante cursores forward-only, read-only.

Antes de que hubiéramos terminado de leerlo ya teníamos a Unai picando un código de demo :_) Cuando la terminó, la ejecutamos y monitorizamos su ejecución mediante el SQL Profiler (capturando eventos de cursores de servidor y de cliente... aunque los de servidor no debería aparecer nunca con ADO.NET, pero por si las moscas ;)), el performance monitor de windows (perfmon.exe) y las vistas de administración dinámicas de SQL Server 2005, y no pudimos apreciar la creación de un solo cursor.

Por una parte fue un alivio (nos parecía overkill que se crearan cursores con todos los DataReaders), pero por otra parte resultó bastante desconcertante el hecho de que en la documentación se hiciera referencia al empleo de cursores, pero en lo práctica no hubiera rastro de ellos. Tras unos minutos de investigación y el comodín de la llamada (gracias Nacho!!) descubrimos que los cursores forward-only, read-only en ADO.NET son los firehose cursors de ADO, que para empezar no son cursores, y por otra parte tampoco apagan fuegos! xD

En realidad, estos 'cursores' son solo un mecanismo para mover de modo rápido datos de un servidor SQL Server al cliente que los ha solicitado. En la práctica, lo que hacen es enviar directamente los datos solicitados por cliente al output buffer del SQL Server. Cuando éste buffer se llena, espera hasta que el cliente pueda recoger estos datos y lo vuelve a llenar de nuevo. Este proceso se repite una y otra vez hasta que el cliente puede recuperar todos los datos.

Como se puede ver, no es el cliente el que va solicitando items como en un cursor tradicional, sino el servidor quien envía todo lo que puede la output buffer. Los bloqueos solo se mantienen mientras el servidor mueve los datos a éste buffer, de modo que no depende de la velocidad de recogida de los datos por parte del cliente, lo que ayuda a mejorar considerablemente el rendimiento y concurrencia. 

En definitiva:

  1. Cuando veamos en la documentación de ADO.NET un cursor forward-only  read-only, no nos llevemos las manos a la cabeza. No son cursores de verdad, y su rendimiento y bloqueos no tienen nada que ver con un cursor ad hoc.
  2. Lo importante no es saber, es tener el teléfono del que sabe xD 
  3. Los aritos de cebolla molan 1024, pero los fingers de queso tiene un mayor Cool Factor(tm).
Remember Yesterday: Java y .NET pueden ser amigos...

Hoy estuve buscando por unas slides que había preparado hace mucho tiempo (de 2003, la primera charla que impartí sobre .NET en mi escuela, la EUITIO) y al volver a verlas, me encontré con una imagen de la que ya me había olvidado. Me hizo mucha gracia, y pensé en compartirla con vosotros:

Starsky & Hutch

¿No es encantadora esta estampa de amistad y buen rollito? :) Mi hermano hizo la magia del photoshop (kudos pa él!!), pero lamentablemente no recuerdo quien me paso la foto original de S & H, pero realmente se merece que le ponga un altar en mi casa y le rinda culto todas las noches antes de irme a dormir! 

Por cierto, y rememorando aquella primera charla mía, un consejo: Cuando estéis dando una charla de introducción a .NET, ¡no expliquéis el algoritmo de recolección de basura! XD

Fair Warning: Problemas depurando con VSTO 2005 SE

A veces parece que nuestros entornos de desarrollo se entretienen viendo como rozamos la desesperación. Ahí va mi advertencia: Outlook puede tratar de reirse un buen rato de vosotros... o al menos, a mi me ha tocado la tontería :) Veréis, yo era un chico de barrio normal, escuchaba Poison y Cinderella, tocaba la guitarra y mi único objetivo en la vida era tener el cardado más molón del universo. Unos años después aquí estoy, sin cardado, sin gruppies, sin fiestas de backstage... y llega un señor muy majo, pero muy liante, y me encarga realizar una aplicación integrada en Outlook con VSTO 2005 SE... toma cisma!

En fin, durante toda esta semana he seguido el proceso habitual de desarrollo: implemento un cachito, lo pruebo, me c*g* en la primera generación de la madre que parió al PM mas grandote que haya en el equipo de las VSTO, corrijo, vuelvo a implementar, vuelvo a probar... Todo bien, todo tan divertido como siempre. Al menos todo iba así hasta ayer por la tarde; a partir de un determinado momento me resultó imposible volver a probar mi aplicación, ya que el add-in simplemente no se cargaba dentro del Outlook!! Ni en modo de depuración, ni en modo release... nada. Aunque aparecia listado en los "Complementos COM" dentro del Outlook 2003, el checkbox no estaba marcado, y adjuntar el depurador no servía para nada, puesto que el modulo parecía no llegar a cargarse.

Finalmente, tras pasar un rato mucho mas grande de lo que me gustaría tener que admitir peleandome con ésto, encontré que la razón se debe a un mecanismo de protección del Outlook ante programadores maizones como un servidor de ustedes. Aparentemente durante alguna ejecución mi código había echo alguna travesura, o no se había cerrado correctamente,  y el Outlook, tratando de protegerse de una ocurrencia de un problema similar en el futuro, marcó el modulo como peligroso (Danger Danger) y lo deshabilitó. Sin embargo, recordemos que VSTO utiliza un cargador generico para los add-ins administrados (un COM Shim, por eso los add-ins aparecen como Complementos COM aunque sean administrados), que por tanto es el modulo que siempre se va a cargar primero. Por ello, en este caso, el modulo marcado como peligroso fue el VSTOLoader.dll, lo que implica que ningún add-in administrado podría volver a ejecutarse en ese Outlook hasta que se sacara la dll de la lista de complementos dehabilitados. Quizá lo más sorprendente de todo el asunto fue encontrar la lista de Elementos Deshabilitados: está en el Acerca De... del Outlook!!!!!!! Alguien podrá explicarme algun día estas cosas??!

Seguramente muchos de vosotros ya os habréis encontrado con este comportamiento, pero a mí me descolocó durante un buen rato y me pareció un buen tema para inaugurar mi blog aquí en geeks.ms. Oh si!! Ya sabía que me olvidaba de algo!! Éste es mi primer post aquí, y sinceramente, no sabía cómo presentarme, así que decidí no hacerlo. Muchos ya nos conocemos, y los demás nos iremos conociendo poco a poco, así que no precipitemos las cosas, no penséis que soy de esos que lo dan todo en la primera cita!! ;)

PD: El nombre de éste blog, Surviving the Night, hace alusión a un temazo de un grupo muy poco conocido; un tema que me suelo poner para cargarme las pilas cuando estoy delante de una pantalla de ordenador a eso de las 3 o 4 de la madrugada, que me ha acompañado durante tantas noches de prácticas de la carrera o proyectos varios... Ofrezco un huevo Kinder(tm) al primero que acierte con el nombre del grupo!! Va en serio!!! 

Posted: 10/11/2006 0:16 por Pablo Alvarez | con 7 comment(s) |
Archivado en: