<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>/dev/GON.cl &#187; Desarrollo</title>
	<atom:link href="http://blog.gon.cl/cat/development/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.gon.cl</link>
	<description>blog respaldo anti-amnesia</description>
	<lastBuildDate>Thu, 12 Jan 2012 19:03:18 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>FirePHP, otra herramienta de depuración de PHP</title>
		<link>http://blog.gon.cl/post/1028</link>
		<comments>http://blog.gon.cl/post/1028#comments</comments>
		<pubDate>Tue, 15 Nov 2011 19:15:35 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[firephp]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=1028</guid>
		<description><![CDATA[Llevo años usando Xdebug para hacer depuración de PHP, pero últimamente estoy ocupando algo más. FirePHP está compuesto de 2 partes, una librería PHP (puede ser usada en versión orientada a objetos o en funciones). La otra parte es una extensión para Firefox (también hay otras extensiones de terceros para otros navegadores, como Google Chrome), [...]]]></description>
			<content:encoded><![CDATA[<p>Llevo años usando Xdebug para hacer depuración de PHP, pero últimamente estoy ocupando algo más.</p>
<p>FirePHP está compuesto de 2 partes, una librería PHP (puede ser usada en versión orientada a objetos o en funciones). La otra parte es una extensión para Firefox (también hay otras extensiones de terceros para otros navegadores, como Google Chrome), que a su vez extiende la funcionalidad de la ya conocida extensión Firebug.</p>
<h2>¿Para que sirve?</h2>
<p>Firebug añade un panel donde se puede llevar control de varios tipos de error que son detectados por el navegador, sobre todo en tiempo de ejecución como lo es con javascript de las páginas web o también de las mismas extensiones de Firefox.</p>
<p>FirePHP añade algo más. Por el lado de la librería, Firebug es capaz de enviar información de depuración a través de las cabeceras HTTP y no en el contenido (como lo hace el reemplazo de la gestión de errores nativa de PHP que añade Xdebug). Esto tiene varias ventajas, por ejemplo:</p>
<ul>
<li>Evita que al desplegarse errores sobre el HTML de un sitio, este se descuadre su diseño, o debido al diseño, no pueda verse bien el error en ciertos casos.</li>
<li>Evitar corrupción de datos cuando PHP genera salidas que no son de texto plano, por ejemplo al generar un PDF dinámicamente o imágenes (con php_gd2).</li>
<li>Al hacer peticiones por ajax, donde generalmente uno &#8220;no ve&#8221; lo que está llegando (con Firebug se puede ver), y por lo tanto tampoco se ve si la salida venía con errores entremedio.</li>
<li>En la misma linea de los 2 puntos anteriores, evita que se corrompa una salida en json o xml al hacer peticiones ajax que vengan con errores.</li>
</ul>
<p>Por el lado del cliente, añade un filtro a Firebug para detectar estas cabeceras y desplegarlas en la Consola de Firebug.</p>
<p>Además, con un pequeño &#8220;hack&#8221;, se pueden redirigir TODOS los errores estándar que salen por pantalla, a las cabeceras, simplemente con un script (en PHP).</p>
<h2>Hermoso, ¿y como lo hago funcionar?</h2>
<p>Simple.</p>
<p><span id="more-1028"></span></p>
<p>En el lado del cliente, instalar las extensiones <a title="Firebug" href="https://addons.mozilla.org/en-US/firefox/addon/firebug/" target="_blank">Firebug</a> y <a title="FirePHP" href="https://addons.mozilla.org/en-US/firefox/addon/firephp/" target="_blank">FirePHP</a>.</p>
<p>En el lado del servidor, solo hace falta <a title="FirePHP" href="http://www.firephp.org/" target="_blank">bajar y e instalar la librería</a> en alguna carpeta que este dentro del <strong>include_path</strong> de PHP. Eso se puede ver en el <strong>php.ini</strong> o vía <strong>phpinfo()</strong>.</p>
<p>Listo. Ahora cada vez que se quiera exponer una variable o dato de PHP por la consola de Firebug, es cosa de llamar una función (o método) que provee FirePHP. Al ejecutar el script se verá ese dato en la consola.</p>
<h2>Redirigir Errores a las cabeceras</h2>
<p>Ahora si además queremos que cualquier error (E_WARNING, E_NOTICE, por ejemplo) se vean a través de la consola de Firebug, entonces además hace falta un hack.</p>
<p>Primero es necesario crear un script php con el siguiente contenido:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">registerErrorHandler<span style="color: #009900;">&#40;</span>
            <span style="color: #000088;">$throwErrorExceptions</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$firephp</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>registerExceptionHandler<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$firephp</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>registerAssertionHandler<span style="color: #009900;">&#40;</span>
            <span style="color: #000088;">$convertAssertionErrorsToExceptions</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
            <span style="color: #000088;">$throwAssertionExceptions</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">ob_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Se debe añadir en la configuración de php.ini, en la directiva <strong>auto_prepend_file</strong>, la ruta directa a un script, llamemoslo &#8220;firephp.php&#8221;. Supongamos que está en c:\www\firephp.php quedaría así:</p>
<p>auto_prepend_file = &#8220;c:\www\firephp.php&#8221;</p>
<p>En mi estación Linux/Mac lo tengo así:</p>
<p>auto_prepend_file = &#8220;/Volumes/Documentos/devel/www/firephp.php&#8221;</p>
<h2>Pruebas</h2>
<p>Nada especial. Es cosa de crear algún script y añadirle algo como:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$var</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'uno'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sadf'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'qwerty'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'tres'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
FB<span style="color: #339933;">::</span><span style="color: #990000;">log</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>y para probar errores:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HOLA, ESTE ES UN FALLO INTENCIONAL'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F1028&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/1028"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/1028"  data-text="FirePHP, otra herramienta de depuración de PHP" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/1028/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mi primer repositorio PPA</title>
		<link>http://blog.gon.cl/post/793</link>
		<comments>http://blog.gon.cl/post/793#comments</comments>
		<pubDate>Mon, 24 Aug 2009 22:36:32 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[9.04]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[jaunty]]></category>
		<category><![CDATA[kde]]></category>
		<category><![CDATA[kopete]]></category>
		<category><![CDATA[pidgin]]></category>
		<category><![CDATA[ppa]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=793</guid>
		<description><![CDATA[Hace algunos días por alguna extraña alineación planetaria, tuve problemas usando kopete, por lo cual&#8230; debí recurrir a la otra opción más a mano, pero del lado oscuro: pidgin. Pero gracias a ese incidente, me topé con un par de cosas interesantes. La primera es que terceros desarrollaron un plugin para pidgin, que permite usar [...]]]></description>
			<content:encoded><![CDATA[<p>Hace algunos días por alguna extraña alineación planetaria, tuve problemas usando kopete, por lo cual&#8230; debí recurrir a la otra opción más a mano, pero del lado oscuro: pidgin.</p>
<p>Pero gracias a ese incidente, me topé con un par de cosas interesantes. La primera es que terceros desarrollaron un plugin para pidgin, que permite usar el chat de Facebook dentro de él. El paquete está disponible a través de <a href="http://code.google.com/p/pidgin-facebookchat/downloads/list">un repositorio de Google Code</a>.</p>
<p>Ya había visto la noticia sobre un plugin similar que estaba cocinando <a href="http://duncan.mac-vicar.com/blog/">Duncan Mac-Vicar</a> para Kopete, pero no le vi mayor interés hasta ahora, que ya había probado el de pidgin.</p>
<p>Durante la semana pasada, baje y compilé las fuentes (y sus dependencias) para probar. Así pude testear el funcionamiento del plugin. Por desgracia aun está muy inmaduro, pero ello no lo hace menos interesante.</p>
<p>Una de las dependencias <strong>kopete-facebook</strong> es <strong><a href="http://flavio.castelli.name/qjson_qt_json_library">qjson</a></strong>, una librería que extiende Qt para añadirle un JSON Parser, necesario para procesar los datos recibidos/enviados por la red de facebook.</p>
<p>Lamentablemente, ni kopete-facebook ni qjson estan empaquetados en ubuntu jaunty (qjson está en 9.10 karmic koala, pero karmic aun está en estado alpha). Tanto Duncan<a href="#duncan">[1]</a> como Flavio<a href="#flavio">[2]</a>, solo ofrecen los paquetes fuente y un paquete para <a href="http://es.opensuse.org/">opensuse</a>.</p>
<p>Entonces, luego que logré compilar ambas librerías se me cruzó por la cabeza&#8230;<em>&#8220;Cualquiera puede hacerse un PPA, ¿y si lo empaqueto para kubuntu y lo subo?&#8221;</em>  Bueno, a eso me dediqué este fin de semana.<br />
<span id="more-793"></span><br />
Gracias a una intensa tarde recordando como diablos empaquetar un <strong>.deb</strong>, y gracias a unas ayuditas de <a href="http://jci.codemonkey.cl/">jci</a>, finalmente hoy hace unos minutos, logré por fin empaquetar y subir sin errores ambas librerías.</p>
<p>Si alguien se anima a probar kopete-facebook, les dejo el repositorio: <a href="https://launchpad.net/~sirgon/+archive/ppa">https://launchpad.net/~sirgon/+archive/ppa</a></p>
<p>Todavía no hay garantía de (1) que el paquete tenga todas las dependencias correctas y menos (2) que el plugin funcione completamente bien. De hecho, el mismo Duncan ya anunció estar en conocimiento de un bug que impide recibir mensajes que nos han respondido. Pero a medida que vea que avanza la cosa, volveré a empaquetar y subir.</p>
<p>Ojala tuviera tiempo para echarle un ojo más detallado al código.<br />
Lo otro, es que mientras aun no está en jaunty tampoco, tal vez en poco tiempo más empaquete y suba <a href="http://konversation.kde.org/">Konversation</a> para KDE4. Ese ya lo tengo compilado, pero me había dado flojera empaquetarlo.</p>
<p>Por alguna razón, siempre los pequeños desastres terminan resultando buena experiencias <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/biggrin.png' alt=':D' class='wp-smiley' /> .</p>
<p>&#8211;<br />
<a name="duncan">[1] Duncan Mac-Vicar, autor del proyecto <a href="http://kopete.kde.org/">Kopete</a>.<br />
<a name="flavio">[2] Flavio Castelli, autor de qjson.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F793&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/793"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/793"  data-text="Mi primer repositorio PPA" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/793/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Respetarte tu mismo debes, (Cr&#237;tica a Joomla #1)</title>
		<link>http://blog.gon.cl/post/676</link>
		<comments>http://blog.gon.cl/post/676#comments</comments>
		<pubDate>Wed, 11 Mar 2009 06:29:27 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[joomla]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[crítica]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=676</guid>
		<description><![CDATA[Mientras trabaja por volver a levantar un sitio que antiguamente usaba joomla 1.0, tuve un peque&#241;a molestia en el panel de control del nuevo 1.5, debido a que me sal&#237;a un mensaje de error. Afortunadamente no era fatal, ya que igualmente pod&#237;a modificar los par&#225;metros del sitio sin mayor inconveniente. Pero es molesto ver que [...]]]></description>
			<content:encoded><![CDATA[<p>Mientras trabaja por volver a levantar un sitio que antiguamente usaba joomla 1.0, tuve un peque&ntilde;a molestia en el panel de control del nuevo 1.5, debido a que me sal&iacute;a un mensaje de error.</p>
<p>Afortunadamente no era fatal, ya que igualmente pod&iacute;a modificar los par&aacute;metros del sitio sin mayor inconveniente. Pero es molesto ver que algo no est&aacute; bien, menos en un sistema grande como lo es Joomla.</p>
<p>El error me indicaba que hab&iacute;a un archivo XML que no se estaba &#8220;parseando&#8221; adecuadamente, pero no me dec&iacute;a cual archivo ni cual error ten&iacute;a.</p>
<p>Entonces decid&iacute; bajar una copia de seguridad del sitio completo, y replicarlo en mi m&aacute;quina local para averiguar el error. Record&eacute; que en linux existen miles de aplicaciones por consola, lo suficientemente poderosas para <strong>parsear</strong> y <strong>validar</strong> los XML&#8217;s de mi sitio.</p>
<p>Ya tuve <a href="http://blog.gon.cl/post/12">una experiencia grata con el comando <strong>find</strong></a>. Pero me faltaba el comando para validar un archivo xml. Buscando encontr&eacute; que posiblemente el comando <strong>xmllint</strong> me podr&iacute;a servir. Aunque finalmente no me ayud&oacute;, revel&eacute; un peque&ntilde;o detalle que no me esperaba.</p>
<p><strong>xmllint</strong> tiene una opci&oacute;n para validar, pero para realizar ese trabajo, requiere que 1) el archivo XML defina un DTD o 2) se le pase por par&aacute;metro. Probando sin usar un DTD por par&aacute;metro: prob&eacute; lo siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">find</span> . <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.xml&quot;</span> <span style="color: #660033;">-exec</span> xmllint <span style="color: #660033;">--noout</span> <span style="color: #660033;">--valid</span> <span style="color: #ff0000;">&quot;{}&quot;</span> \;</pre></div></div>

<p>Lamentablemente, el resultado no fue lo que esperaba. TODOS los XML salvo uno, eran inv&aacute;lidos, debido a que NO TEN&Iacute;AN definido el DTD. Gracias a ese archivo que s&iacute; lo ten&iacute;a, descubr&iacute; que joomla TIENE en su sitio un archivo DTD para que los desarrolladores lo incluyan en sus XML de configuraci&oacute;n. De esta forma, el desarrollador obliga a que sus archivos XML tengan la estructura que el sistema requiere.</p>
<p>Lo peor&#8230; ese &uacute;nico archivo v&aacute;lido, era de un plugin de terceros y no de los desarrolladores oficiales. Es decir, los desarrolladores oficiales de joomla NO RESPETAN sus propias reglas al escribir el c&oacute;digo.</p>
<p>Finalmente, xmllint no era lo que estaba buscando, ya que solo deb&iacute;a comprobar cual era el o los archivos mal formados (etiquetas mal cerradas, mal anidadas, &#8230;). Como no sab&iacute;a, consulte en una lista de correo (una de las que tengo en la lista de comunidades), donde me dieron la soluci&oacute;n: <strong>xmlwf</strong>.</p>
<p>Simplemente cambi&eacute; el comando anterior por el siguiente y asunto arreglado:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">find</span> . <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.xml&quot;</span> <span style="color: #660033;">-exec</span> xmlwf <span style="color: #ff0000;">&quot;{}&quot;</span> \;</pre></div></div>

<p>Encontr&eacute; los culpables (eran 2), los correg&iacute; y di por terminado el asunto.<br />
Pero me qued&eacute; con el sabor amargo de la despreocupaci&oacute;n que los desarrolladores de Joomla han tenido en un detalle tan simple. &iquest;Que confianza me dan para cuando aparezca una nueva actualizaci&oacute;n del sistema?</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F676&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/676"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/676"  data-text="Respetarte tu mismo debes, (Cr&iacute;tica a Joomla #1)" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/676/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cuando un comentario cambia el significado</title>
		<link>http://blog.gon.cl/post/515</link>
		<comments>http://blog.gon.cl/post/515#comments</comments>
		<pubDate>Wed, 14 Jan 2009 17:39:05 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=515</guid>
		<description><![CDATA[Mirar c&#243;digo ajeno por primera vez, es como un arque&#243;logo encontrando una civilizaci&#243;n perdida. A menos que contemos con una piedra rosseta (o mejor a&#250;n, conozcamos el lenguaje perdido), la &#250;nica forma de decodificarlo es &#8220;al tanteo&#8221;. Los &#250;ltimos d&#237;as, hab&#237;a experimentado una falla inusual en mi aplicaci&#243;n lectora de huellas. A veces guardando el [...]]]></description>
			<content:encoded><![CDATA[<p>Mirar c&oacute;digo ajeno por primera vez, es como un arque&oacute;logo encontrando una civilizaci&oacute;n perdida.</p>
<p>A menos que contemos con una piedra rosseta (o mejor a&uacute;n, conozcamos el lenguaje perdido),  la &uacute;nica forma de decodificarlo es &#8220;al tanteo&#8221;.</p>
<p>Los &uacute;ltimos d&iacute;as, hab&iacute;a experimentado una falla inusual en mi aplicaci&oacute;n lectora de huellas. A veces guardando el &#8220;template&#8221; de la huella en la base de datos, quer&iacute;a guardar una segunda o tercera lectura, pero se segu&iacute;a guardando el primero. Adem&aacute;s, solo me identificaba 1 huella de todas las guardadas.</p>
<p>Volviendo al ejemplo que ven&iacute;a junto al kit de desarrollo, encontr&eacute; el motivo, tanto del fallo como de mi confusi&oacute;n.</p>
<p>Mientras desarrollaba el c&oacute;digo del lector de huellas en C#, encontr&eacute; un m&eacute;todo trabajaba con la base de datos, pero en un lugar donde no deb&iacute;a. Lo primero que hice hace meses, fue separar esa porci&oacute;n de c&oacute;digo a otro archivo qu corresponde a mi capa de &#8220;Modelo&#8221;. La linea de la discordia fue la siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> identify<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> <span style="color: #6666cc; font-weight: bold;">int</span> score, <span style="color: #0600FF; font-weight: bold;">ref</span> AxGrFingerXLib<span style="color: #008000;">.</span><span style="color: #0000FF;">AxGrFingerXCtrl</span> grfingerx<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    GRConstants result<span style="color: #008000;">;</span>
    <span style="color: #6666cc; font-weight: bold;">int</span> id<span style="color: #008000;">;</span>
    SqlDataReader rs<span style="color: #008000;">;</span>
    TTemplate tptRef<span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// &lt;= EL FALLO ESTA ACA</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// M&amp;aacute;s c&amp;oacute;digo...</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>El encabezado del m&eacute;todo ten&iacute;a un comentario que dec&iacute;a algo as&iacute; como &#8220;compara el <strong>template</strong> de la lectura con todos los <strong>templates</strong> obtenidos desde la base de datos&#8221;. Por lo tanto, asum&iacute; que &#8220;TTemplate tptRef&#8221; significaba &#8220;Huella de referencia&#8221;. No s&eacute; que concepto de &#8220;medida de referencia&#8221; tuvo el programador del ejemplo, pero para m&iacute;, una regla o un peso es una unidad de medida de referencia. Es decir &#8220;Mi <strong>template</strong> se compara con todos los tuyos&#8221;.</p>
<p>Sin embargo, para el programador del ejemplo, &#8220;Huella de referencia&#8221; significaba &#8220;cada uno de los templates de la base de datos&#8221;. Es decir, &#8220;Mi <strong>template</strong> en cada vuelta del ciclo, ser&aacute; el mismo de la base de datos y se comparar&aacute; con tu lectura&#8221;.</p>
<p>Ese simple cambio de significado, me ech&oacute; a perder el c&oacute;digo. Ahora despu&eacute;s de mucho tiempo de haber hecho esos cambios, logr&eacute; entender el funcionamiento de ese m&eacute;todo solo leyendo el c&oacute;digo, pero de no haber usado como &#8220;medida de referencia&#8221; el c&oacute;digo del ejemplo sin modificar, me habr&iacute;a visto obligado a investigar a fondo &#8220;donde se quedaba pegado en la lectura de la huella&#8221;.</p>
<p>La moraleja es entonces, fijarse en todas las interpretaciones que pueda tener la documentaci&oacute;n o los comentarios. Si somos nosotros los que documentamos, <strong>debemos</strong> evitar que un detalle tan peque&ntilde;o pueda cambiarle todo el sentido.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F515&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/515"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/515"  data-text="Cuando un comentario cambia el significado" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/515/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Malabareando 900MB de Bases de datos SQL</title>
		<link>http://blog.gon.cl/post/508</link>
		<comments>http://blog.gon.cl/post/508#comments</comments>
		<pubDate>Tue, 13 Jan 2009 08:19:42 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[respaldo]]></category>
		<category><![CDATA[sql server]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=508</guid>
		<description><![CDATA[Y lo chistoso no fue el peso. Continuando con el retrasado proyecto del lector de huellas para el control de acceso, me top&#233; con un problema de aquellos&#8230; La aplicaci&#243;n actual de control de acceso funciona con SQL Server 7 sobre Windows 2000, una reliquia mal viviente. La herramienta de manejo de la base de [...]]]></description>
			<content:encoded><![CDATA[<p>Y lo chistoso no fue el peso.</p>
<p>Continuando con el retrasado <a href="http://blog.gon.cl/2008/09/06/desafio-controlar-acceso-a-traves-de-huellas/">proyecto del lector de huellas</a> para el control de acceso, me top&eacute; con un problema de aquellos&#8230;</p>
<p>La aplicaci&oacute;n actual de control de acceso funciona con SQL Server 7 sobre Windows 2000, una reliquia <span style="text-decoration: line-through;">mal</span> viviente. La herramienta de manejo de la base de datos (SQL Management) asociada a esa versi&oacute;n, es un verdadero misterio en funcionalidades. Por alguna raz&oacute;n, &#8220;Generar consultas SQL&#8221; a una base de datos, solo genera los modelos de las tablas, pero ni rastro de los registros. Finalmente no logr&eacute; sacar esos datos, porque desde generar una copia de seguridad hasta volcar todo a un archivo de texto plano, generaba un lindo &#8220;error desconocido&#8221;.</p>
<p>No se quien lo logr&oacute;, pero hoy recib&iacute; un DVD con los 900MB de tablas y registros de esas bases. El archivo era un copia de seguridad<strong> <strong>respaldo.bkp</strong>.</strong></p>
<p>Lo primero que hice, fue tratar de jugar con &eacute;l  <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/tongue.png' alt=':p' class='wp-smiley' /> .</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F508&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/508"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/508"  data-text="Malabareando 900MB de Bases de datos SQL" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/508/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problemas de migraci&#243;n (y cr&#237;tica a wordpress #1)</title>
		<link>http://blog.gon.cl/post/464</link>
		<comments>http://blog.gon.cl/post/464#comments</comments>
		<pubDate>Thu, 08 Jan 2009 23:21:59 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[crítica]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=464</guid>
		<description><![CDATA[Disculpa, pero esta entrada está disponible sólo en English. Tweet]]></description>
			<content:encoded><![CDATA[<p>Disculpa, pero esta entrada está disponible sólo en <a href="http://blog.gon.cl/en/cat/development/feed">English</a>.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F464&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/464"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/464"  data-text="Problemas de migraci&oacute;n (y cr&iacute;tica a wordpress #1)" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/464/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gonium tiene nuevo blog</title>
		<link>http://blog.gon.cl/post/402</link>
		<comments>http://blog.gon.cl/post/402#comments</comments>
		<pubDate>Mon, 29 Dec 2008 09:52:23 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[temas wordpress]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=402</guid>
		<description><![CDATA[Ya que tengo espacio, hay que aprovecharlo. Un lugar donde explicar las cosas Mientras no tengo un m&#243;dulo de para blogear funcional en Gonium, no me queda otra que usar al enemigo (WordPress). Lo cual no es del todo malo, sino justamente lo contrario. La idea de tener un blog exclusivamente para el desarrollo de [...]]]></description>
			<content:encoded><![CDATA[<p>Ya que tengo espacio, hay que aprovecharlo.</p>
<h2>Un lugar donde explicar las cosas</h2>
<p>Mientras no tengo un m&oacute;dulo de para blogear funcional en Gonium, no me queda otra que usar al enemigo (WordPress). Lo cual no es del todo malo, sino justamente lo contrario.</p>
<p><a href="http://gon.boaboa.org/wblog/"><img class="aligncenter size-full wp-image-400" title="gonium_blog_120x60" src="http://blog.gon.cl/wp-content/uploads/2008/12/gonium_blog_120x60.png" alt="gonium_blog_120x60" width="120" height="60" /></a></p>
<p>La idea de tener un blog exclusivamente para el desarrollo de Gonium, me permitir&aacute; poder dejar en claro cuales son las ideas que se est&aacute;n implementando o se desarrollaran a futuro, all&aacute; en su propio lugar. Hay mucho por hacer, por lo tanto, mantener una bit&aacute;cora de desarrollo (m&aacute;s que un precario Roadmap), espero me sirva mucho m&aacute;s.</p>
<p>Un detalle importante: el blog,  el proyecto en Google en Code, los mensajes en Twitter, los commits de svn e incluso la documentaci&oacute;n autogenerada del API, se mantendr&aacute;n todos en idioma ingl&eacute;s principalmente.</p>
<p>La raz&oacute;n de esto es muy sencilla: <strong>universalidad</strong>. Aunque no me gusta la idea, lamentablemente en comunicaciones, el ingl&eacute;s es lo m&aacute;s universal. No por ser de origen chileno quisiera que solo alg&uacute;n amigo m&iacute;o de ac&aacute; lo ocupe. Espero que a todo a quien le sirva tenga la posibilidad de ocuparlo. &iquest;Quien me dice que alguien por ah&iacute; no estar&aacute; ya husmeando el c&oacute;digo? &iquest;Y si este alguien hablara en italiano? &iquest;O franc&eacute;s? &iquest;o alem&aacute;n? &iquest;o chino?</p>
<p>Adem&aacute;s, habiendo tenido experiencia en el proyecto <a href="http://gdt.sourceforge.net">GDT</a>, not&eacute; como muchos usuarios, aun cuando en su mayor&iacute;a se trataba de hispano-parlantes, simplemente no les gust&oacute; la idea de usar objetos y m&eacute;todos nombrados en espa&ntilde;ol. No entiendo estas ma&ntilde;as, pero se que son frecuentes y extendidas. De hecho, <a href="http://edsiper.linuxchile.cl/blog/">Eduardo Silva</a>, en su charla de <a href="http://monkeyd.sourceforge.net/blog/">Monkey HTTP Daemon</a> en el <a href="http://2008.encuentrolinux.cl/">Encuentro Linux</a>, mencion&oacute; haber tenido ese problema con los hispano-parlantes, as&iacute; que decidi&oacute; simplemente dejar todo, lista de correo, blog, documentaci&oacute;n, etc, en ingl&eacute;s. Esta vez, adoptar&eacute; la misma idea y ver&eacute; que sucede.</p>
<p>Por el momento, no espero una explosi&oacute;n de usuarios, ni mucho menos mientras la versi&oacute;n funcional brilla por su ausencia, pero s&iacute; espero ideas, comentarios y en general <strong>feedback.</strong> Ya me han estado preguntando cosas como &#8220;&iquest;est&aacute;s reclutando gente?&#8221;, lo cual es un alivio para esos minutos en que me cuestiono el &#8220;&iquest;para que diablos estoy haciendo algo que solo me importa a m&iacute;?&#8221;. Por si acaso, s&iacute; estoy reclutando gente <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/=B_1.gif' alt=':B' class='wp-smiley' /> . &iquest;Desarrolladores en Zend Framework? Bienvenidos! Cualquier tipo de aporte ser&aacute; igualmente bien recibido, ya sea de parte de un <strong>PHP</strong>ero, <strong>jQuery</strong>sta, <strong>CSS</strong>ero, Traductor, Dise&ntilde;ador o Art&iacute;sta son plenamente bienvenidos.</p>
<p><span id="more-402"></span></p>
<h2>Confirmando lo que pensaba</h2>
<p>Gracias a todo esto, tuve una ocurrencia del tipo &#8220;oh, &iquest;y si hago que el template de wordpress sea el mismo que el de Gonium?&#8221;. Con eso basto para ponerme a meter un poco de mano en la creaci&oacute;n de un tema. Nuevamente confirmo lo que pens&eacute; hace mucho tiempo atr&aacute;s acerca de wordpress, es espagetti.</p>
<p>Realmente es una de las APIs (si es que puede siquiera llamarse as&iacute; a su &#8220;codex&#8221;) m&aacute;s espantosas que he visto. Gracias a que participo en tecnosquad.org y a que dedicamos un d&iacute;a para &#8220;la &eacute;pica b&uacute;squeda de un tema nuevo&#8221;, fue como aquella tarde recolecte bastantes temas atractivos y los guarde &#8220;por si acaso&#8221;. Finalmente no encontramos nada que nos hiciera sentir ese &#8220;wow, es tema est&aacute; pintado para tecnosquad&#8221;, pero igualmente la b&uacute;squeda me trajo un buen producto.</p>
<p>Ocupe uno de esos temas para codear el mio. Entonces fue cuando note la importancia de ciertos detalles.</p>
<p>El primero es sobre el tama&ntilde;o de un tema. Por ejemplo los temas m&aacute;s &#8220;profesionales&#8221; suelen tener m&aacute;s archivos e incluso permiten agregar paneles de opciones al backend de wordpress. En esos archivos extra, los temas definen sus propias funciones, las cuales no tienen ninguna interfaz com&uacute;n, cada tema implementa sus cosas a su pinta. Algunos usaban clases/objetos, pero la mayor&iacute;a solo funciones sueltas.</p>
<p>Otro detalle importante, es que aun cuando las funciones &#8220;del n&uacute;cleo&#8221; para plantillas est&aacute;n documentadas, el solo hecho de leer un archivo fuente resulta ca&oacute;tico. Casi nada de pulcritud, incluso me atrevo a aventurar que ning&uacute;n tema de los que termine bajando (y fueron muchos), ni si quiera ten&iacute;an el c&oacute;digo propiamente indentado.</p>
<p>Una de las primeras cosas que aprend&iacute; con el Zend Framework, fue el patr&oacute;n de dise&ntilde;o &#8220;Two Steps&#8221; para plantillas, es decir, una plantilla &#8220;layout&#8221; que crea el esqueleto de la p&aacute;gina, y luego se agregan los contenidos sobre este layout, que pueden provenir de otros scripts de vista. En wordpress, simplemente no existe tal cosa. No quise mirar m&aacute;s hacia adentro del c&oacute;digo, pero lo que vi por fuera (las plantillas), me dan m&aacute;s ganas de &#8220;terminar&#8221; de una vez una versi&oacute;n usable de Gonium. Estoy seguro que ser&iacute;a una delicia para los dise&ntilde;adores.</p>
<p>M&aacute;s tarde, cuando ya pueda blogear tranquilo en Gonium, migrar&eacute; el contenido y me deshar&eacute; del wordpress. La idea principal est&aacute; m&aacute;s viva que nunca: el objetivo es crear un administrador de contenido de prop&oacute;sito general, pero BIEN HECHO.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F402&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/402"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/402"  data-text="Gonium tiene nuevo blog" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/402/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como guardar datos en una Cookie Segura (y un PHP FAIL)</title>
		<link>http://blog.gon.cl/post/392</link>
		<comments>http://blog.gon.cl/post/392#comments</comments>
		<pubDate>Thu, 25 Dec 2008 08:04:04 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[autenticación]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[criptografía]]></category>
		<category><![CDATA[hmac]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[seguridad]]></category>
		<category><![CDATA[zend auth]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=392</guid>
		<description><![CDATA[Los &#250;ltimos d&#237;as los he dedicado al estudio de uno de esos viejos problemas que nunca hab&#237;a podido resolver. Consiste en el almacenamiento &#8220;seguro&#8221; de datos que viajan en un canal inseguro y se almacenan en un medio inseguro. Puntualmente, hablo de COOKIES. Cuando hablamos de protocolo HTTP(S), las cookies son el &#250;nico &#8220;repositorio de [...]]]></description>
			<content:encoded><![CDATA[<p>Los &uacute;ltimos d&iacute;as los he dedicado al estudio de uno de esos viejos problemas que nunca hab&iacute;a podido resolver.</p>
<p>Consiste en el almacenamiento &#8220;seguro&#8221; de datos que viajan en un canal inseguro y se almacenan en un medio inseguro. Puntualmente, hablo de COOKIES. Cuando hablamos de protocolo HTTP(S), las cookies son el &uacute;nico &#8220;repositorio de datos&#8221; o almacenamiento persistente en el lado del cliente (navegador) con el que podemos trabajar.</p>
<p>En las cookies, podemos guardar las preferencias de un usuario (por ejemplo, el idioma que escoja, la &uacute;ltima p&aacute;gina que vi&oacute;, etc&#8230;). Y el problema puntual con cookies: <strong>guardar la identidad del usuario para &#8220;recordar&#8221; su sesi&oacute;n</strong>.</p>
<p>El peligro esta en el como se guarda esta identidad. Lo bueno es que ya encontr&eacute; un m&eacute;todo que me convenci&oacute;, y realmente es bastante &#8220;simple&#8221; como algoritmo. Lo que no fue simple fue la implementaci&oacute;n.</p>
<p>La verdad es que no se como pretend&iacute;a completar el primer punto de mi roadmap (Lista de control de acceso o ACL) sin tener primero un m&eacute;todo decente de autenticaci&oacute;n. Al menos ya di con una respuesta.</p>
<p><span id="more-392"></span></p>
<h2>El problema de la autenticaci&oacute;n por cookie</h2>
<p>Para autenticar al usuario, necesitamos informaci&oacute;n de este que no diga &#8220;ah! este usuario es Perico Los palotes y no Pedro Juan Diego&#8221;. El problema se reduce entonces a &#8220;que dato guardar en la cookie, que sea &uacute;nico por cada usuario&#8221;.</p>
<h3>El nombre de usuario o <em><strong>ID</strong></em>entificador</h3>
<p>Una soluci&oacute;n simple es, por ejemplo, guardar el nombre de usuario o un n&uacute;mero &#8220;ID&#8221;. Esto ser&iacute;a una soluci&oacute;n v&aacute;lida, de no ser por lo extremadamente inseguro que significa. Si guardo solo el nombre o id del usuario, cualquier persona podr&iacute;a crear una cookie en su navegador con la identidad de otra persona. Finalmente entrar&iacute;a a la web y ya estar&iacute;a autenticado. M&aacute;s que inseguro, es extremadamente est&uacute;pido.</p>
<h3>El nombre de usuario + clave</h3>
<p>Para obstaculizar un poco un eventual ataque, podr&iacute;amos conciderar a&ntilde;adir un segundo campo, con la contrase&ntilde;a del usuario. Pero nuevamente, ser&iacute;a desastroso en t&eacute;rminos de seguridad. Ahora la informaci&oacute;n de la sesi&oacute;n, estar&iacute;a a la vista de cualquier persona que ocupe f&iacute;sicamente el mismo equipo. O peor, un atacante remoto que haya podido ver la cookie (v&iacute;a malware o interceptando la comunicaci&oacute;n). Este atacante podr&iacute;a iniciar la sesi&oacute;n por usuario y contrase&ntilde;a sin problemas.</p>
<p>Otra soluci&oacute;n, consiste en encriptar la clave y desencriptarla en el servidor, pero solo ser&iacute;a una distracci&oacute;n, porque el atacante igualmente podr&iacute;a clonar la cookie y autenticarse, a pesar de estar encriptada la contrase&ntilde;a. Lo mismo pasar&iacute;a si en vez de encriptarla, se contara con una segunda &#8220;clave&#8221;, que solo fuera v&aacute;lida por cookie. No ser&iacute;a posible iniciar sesi&oacute;n de forma cl&aacute;sica, pero si se podr&iacute;a directamente copiando la clave.</p>
<p>Entonces &iquest;que guardar en la cookie para autenticar al usuario? Hace a&ntilde;os, cuando realiz&eacute; esta pregunta en diversos foros, recib&iacute; como respuesta que no hab&iacute;a soluci&oacute;n perfecta, pero si quer&iacute;a hacer algo que ofusque un ataque.</p>
<h3>Contrastar una clave aleatoria con una clave en la base de datos</h3>
<p>Buscando una soluci&oacute;n, llegue a una implementaci&oacute;n de Cookies de Autenticaci&oacute;n, consistente en un <a href="http://www.devshed.com/c/a/PHP/Creating-a-Secure-PHP-Login-Script/">sistema de login</a>. En esa implementaci&oacute;n, se pone el enfasis de la seguridad en la IP del usuario. Pero obviando ese dato, el algoritmo combina el id de sesi&oacute;n de PHP, las cookies y la base de datos, de tal modo que entre esos 3 medios de almacenamiento se guarden &#8220;claves&#8221;, las cuales se contrastar&aacute;n entre los 3 para autenticar los datos.</p>
<p>No es del todo  malo, pero resta rendimiento, debido a que hace consultas extras a la base de datos y muchas comprobaciones.</p>
<p>Lo contraproducente del asunto, es que el dise&ntilde;o de este algoritmo impedir&iacute;a que un usuario guarde su sesi&oacute;n en m&aacute;s de un navegador, porque cada vez que se genere la clave aleatoria nueva, se pierde la validez de las cookies guardas antes en otros navegadores. Peor a&uacute;n, si inclu&iacute;mos la IP como un dato para comprobar la validez de la cookie, no servir&aacute; de nada con usuarios que tengan conexiones a internet con IP din&aacute;mica.</p>
<p>&iquest;Entonces, el problema tiene soluci&oacute;n?</p>
<h2>Una soluci&oacute;n elegante</h2>
<p>Leyendo m&aacute;s acerca de este problema en general, mir&aacute;ndolo desde afuera de la visi&oacute;n cezgada de PHP, logr&eacute; encontrar un <a href="http://www.cse.msu.edu/%7Ealexliu/publications/Cookie/cookie.pdf">paper muy interesante</a> (solo 3 p&aacute;ginas). Parte planteando las mismas interrogantes y falencias sobre otros algoritmos como los que me hab&iacute;a planteado, con la diferencia de que propone soluciones a cada uno de los problemas y los combina en un solo algoritmo. M&aacute;s interesante a&uacute;n, es que el paper describe el m&eacute;todo completo, pero no se ciega en un lenguaje en particular donde implementarlo (navegando encontr&eacute; incluso que fue implementado en python).</p>
<p>Por si el hecho de que los autores del paper son doctores en computaci&oacute;n y expertos en criptograf&iacute;a fuera poco, una de las cosas que me dio confianza (aunque suene burdo), es que <a href="http://boren.nu/archives/2007/12/17/secure-cookies-and-passwords/">el mismo wordpress</a> y otros sistemas estar&iacute;an usando este m&eacute;todo de autenticaci&oacute;n por cookies.</p>
<p>Haciendo otra busqueda, me tope con alguien que <a href="http://bigornot.blogspot.com/2008/06/securing-cookies-php-implementation.html">lo implemento en PHP</a>, y adem&aacute;s <a href="http://bigornot.blogspot.com/2008/06/zendauth-and-secure-cookies.html">implement&oacute; un adaptador</a> para Zend_Auth.</p>
<p>Finalmente, tom&eacute; prestado el c&oacute;digo de ambas clases, la manejadora de <a href="http://code.google.com/p/gonium/source/browse/trunk/application/library/Rox/Crypt/HmacCookie.php">cookies seguras</a> y la adaptadora para Zend_Auth), y las incorpor&eacute; en mi proyecto.</p>
<p>Arregle uno que otro defecto que ten&iacute;an:</p>
<ul>
<li>Ya no requiere mcrypt (que a veces no est&aacute; instalado en los hostings). La caracter&iacute;stica de alta-confidencialidad es opcional y funciona solo con mcrypt activado, sino por defecto usa el modo de baja-confidencialidad.</li>
<li>El dato de entrada deb&iacute;a ser un string. Ahora puede ser cualquier dato soportado por php, excepto &#8220;recursos&#8221;. Es decir, se pueden almacenar incluso objetos.</li>
</ul>
<p>Hay una mejora que a&uacute;n no implemento, que consiste en aplicar un hash al campo &#8220;username&#8221;, de esta forma, aumenta un poco m&aacute;s la confidencialidad del usuario, debido a que un administrador o un atacante no podr&iacute;a saber exactamente &#8220;quien fue el que inicio la sesi&oacute;n en el sitio&#8221; alguna vez, tan solo mirando las cookies. De todos modos, la identidad y rol los guardar&iacute;a en el campo &#8220;data&#8221; serializados y codificados (y si es posible, encriptados tambi&eacute;n).</p>
<h2>Y para rematar&#8230; &iquest;PHP Bug?</h2>
<p>Como en pr&aacute;cticamente todos mis desarrollos, me he topado con <em>Expedientes X</em>. En esta ocasi&oacute;n, descubr&iacute; un comportamiento medio curioso con la serializaci&oacute;n de obejtos. La serializaci&oacute;n de variables permite convertir el valor y el tipo del dato (aunque sea compuesto como un array o un objeto) en una representaci&oacute;n &#8220;almacenable&#8221; (en este caso, una cadena de texto).</p>
<p>Antes, no hab&iacute;a tenido problemas con esto, pero ahora, para implementar el algoritmo de Cookie Segura, me vi forzado a usar serializaci&oacute;n. Lo que no comprendo del todo, es porque al serializar objetos con atributos protegidos o privados, aparecieron unos caracteres raros entremedio. Curiosamente al pasar la misma cadena por otras funciones (como base64_encode/decode y las mcrypt), finalmente obtenia la misma cadena serializada, pero esta vez limpia de esos caracteres raros.</p>
<p>Extra&ntilde;amente, no provoc&oacute; ning&uacute;n efecto adverso al deserializar los datos, por lo tanto, conservaban su integridad como era esperado.</p>
<p>Lo malo del asunto, es que el algoritmo de cookies seguras, requiere usar el campo &#8220;data&#8221; guardado en la cookie para formar la &#8220;llave&#8221; que comprueba la validez de la cookie. Si la cadena obtenida al desencriptar el dato de la cookie retorna &#8220;limpio&#8221;, entonces obviamente no concuerda con la cadena &#8220;sucia&#8221; que formo la llave inicial, y por lo tanto resulta en una cookie inv&aacute;lida, a&uacute;n cuando el dato estaba bueno.</p>
<p>Si alguien desea probar si &#8220;su php&#8221; tambi&eacute;n tiene hipo, pueden probar este sencillo script.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> data
<span style="color: #009900;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'123'</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$b</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'abc'</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'xyz'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> data<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Can you see a fail?</span></pre></div></div>

<p>En algunos casos, al parecer la salidad es correcta, es decir, sin ning&uacute;n caracter raro metido entremedio. En otros casos (como el m&iacute;o y otros m&aacute;s que me ayudaron comprob&aacute;ndolo), s&iacute; aparec&iacute;an bichos en la salida. Una de las sospechas, recaen en que los que tuvimos la falla, estar&iacute;amos ocupando un &#8220;locale&#8221; en espa&ntilde;ol en el sistema, encambio los que no tienen el fallo, usaban su &#8220;locale&#8221; en ingl&eacute;s. Espero (nuevamente) que el futuro motor de PHP6 deje de una vez de ser tan sencible a los cambios de &#8220;encoding&#8221;, tanto por el <strong>idioma del sistema</strong> en que corre, como por <strong>los scripts de entrada</strong> y por el texto plano de <strong>salida</strong>.</p>
<p>No se en realidad a que se debe esto, incluso sospeche que esto se trataba de un bug en ubuntu, pero finalmente result&oacute; no ser tal.</p>
<p>Finalmente, mi &#8220;workaround&#8221; consisti&oacute; en modificar a&uacute;n m&aacute;s el algoritmo, de tal modo que la llave la form&eacute; con un hash del objeto serializado, en vez del objeto serializado por s&iacute; solo. Esto agrega unos cuantos milisegundos y operaciones extra (despreciables en todo caso), pero al menos logr&eacute; &#8220;universalizar&#8221; el mismo script, que era el objetivo primario.</p>
<p>Al menos, creo que aprend&iacute; bastantes cosas tratando de resolver este poblema.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F392&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/392"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/392"  data-text="Como guardar datos en una Cookie Segura (y un PHP FAIL)" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/392/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Google Chrome: Jurel tipo Salm&#243;n</title>
		<link>http://blog.gon.cl/post/365</link>
		<comments>http://blog.gon.cl/post/365#comments</comments>
		<pubDate>Fri, 12 Dec 2008 20:37:37 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Navegador]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[humor]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=365</guid>
		<description><![CDATA[Talla(*) para webmasters: HTTP_USER_AGENT Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.36 Safari/525.19 (*) Talla (espa&#241;ol chilensis): d&#237;cese de broma o humorada Tweet]]></description>
			<content:encoded><![CDATA[<p>Talla(*) para webmasters:</p>
<table style="border-collapse:collapse;margin-left:auto;margin-right:auto;text-align:left;" border="0" cellpadding="3" width="600">
<tbody>
<tr>
<td class="e" style="border:1px solid #000000;font-family:sans-serif;font-size:75%;vertical-align:baseline;background-color:#ccccff;font-weight:bold;color:#000000;">HTTP_USER_AGENT</td>
<td class="v" style="border:1px solid #000000;font-family:sans-serif;font-size:75%;vertical-align:baseline;background-color:#cccccc;color:#000000;">Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.36 Safari/525.19</td>
</tr>
</tbody>
</table>
<p>(*) Talla (espa&ntilde;ol chilensis): d&iacute;cese de broma o humorada</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F365&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/365"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/365"  data-text="Google Chrome: Jurel tipo Salm&oacute;n" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/365/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gonium, nuevo demo y nuevos componentes</title>
		<link>http://blog.gon.cl/post/357</link>
		<comments>http://blog.gon.cl/post/357#comments</comments>
		<pubDate>Thu, 11 Dec 2008 04:17:46 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[docbook]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[phpdocumentor]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=357</guid>
		<description><![CDATA[Gracias a la wena onda de Tecnoman, que se auspicio con hosting y me dejo hincharle las pelotas para que instalara PDO en un servidor en producci&#243;n, tengo el demo de Gonium en un hosting nuevo. Ahora intentar&#233; de alg&#250;n modo recompensar aquello, posteando m&#225;s seguido en tecnosquad.org. Aprovechando eso, sub&#237; una copia m&#225;s reciente. [...]]]></description>
			<content:encoded><![CDATA[<p>Gracias a la <em>wena onda</em> de Tecnoman, que se auspicio con hosting <span style="text-decoration:line-through;">y me dejo hincharle las pelotas para que instalara PDO en un servidor en producci&oacute;n</span>, tengo el demo de Gonium en un <a href="http://gon.boaboa.org">hosting nuevo</a>. Ahora intentar&eacute; de alg&uacute;n modo recompensar aquello, posteando m&aacute;s seguido en <a href="http://tecnosquad.org">tecnosquad.org</a>.</p>
<p>Aprovechando eso, sub&iacute; una copia m&aacute;s reciente.</p>
<p>Hace unos d&iacute;as agregu&eacute; al trunk del repositorio, una copia propia del proyecto <cite><a href="code.google.com/p/zend-framework-datagrid/"><strong>zend-framework-datagrid</strong></a></cite>, con la diferencia de que mi copia permite traducirlo con Zend_Translate y los comentarios est&aacute;n corregidos. Tambi&eacute;n correg&iacute; unos <em>warnings</em> menores. Adem&aacute;s le cambi&eacute; el prefijo a las clases de &#8220;Core_&#8221; (originalmente en zf-datagrid) a &#8220;Rox_&#8221;, para darle concordancia a mi estructura de directorios. Podr&iacute;a decir entonces que es un peque&ntilde;o fork <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/=B_1.gif' alt=':B' class='wp-smiley' /> </p>
<p>Tambi&eacute;n agregu&eacute; todo jQuery UI al directorio p&uacute;blico. Una ejemplo de esto es la peque&ntilde;a demostraci&oacute;n con el efecto acorde&oacute;n que le agregu&eacute; al widget de Login.</p>
<p>Y por &uacute;ltimo, agregu&eacute; un directorio con XML&#8217;s en formato docbook, para poder usarlos en conjunto con la documentaci&oacute;n creada con phpDocumentor.</p>
<p>Espero tener una documentaci&oacute;n un poco m&aacute;s completa m&aacute;s adelante.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F357&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/357"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/357"  data-text="Gonium, nuevo demo y nuevos componentes" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/357/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 3.503 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-05 14:30:22 -->

