lluvia en estambul

15 de septiembre de 2009

La fecha, 9 de septiembre en Estambul, situación, datacenter de Vodafone... llegada de tormentas torrenciales. Momento desesperado el minuto 3:20.



configuración y uso de fetchmail

14 de septiembre de 2009

fetchmail es una utilidad para UNIX/Linux que nos permite hacer de cliente POP/IMAP y descargar el correo de un buzón (o varios buzones) en local. Originalmente se basaba en otro proyecto llamado popclient hasta que al introducir el protocolo IMAP en 1996 cambio de nombre.

Puede ser utilizado para varias cosas. Una de ellas es para los usuario que no tienen acceso directo a Internet y es un admin (o ellos mismo) el que acceden a la cuenta de correo bajo fetchmail y le entregan el correo es su buzón local de su maquina. Yo, por ejemplo, lo utilizo para acceder a un buzón de correo donde hay multitud de correos para varios destinatarios y lo injecto al MTA de Postfix para que los reparta entre los buzones de los usuario finales.

Permite hacer pool de cuentas, acceder via SSL, liminar el numero de mensajes a descargar para reducir el ancho de banda, programar los pools cada cierto tiempo, descargar correos de un dominio concreto, reescribir direcciones de correo, etc.

A petición popular de zimbra-grupo se ha escrito un manual de fetchmail con casos reales de configuraciones.

configuración y uso de fetchmail.pdf

Más información:
+ Manual de fetchmail

google apps como servidor de correo de backup

7 de septiembre de 2009

Google Apps tiene una versión gratuita que puede servirnos para usarla como servidor de correo secundario (backup) en nuestra infraestructura de empresa. La idea es que cuando nuestro servidor de correo principal este offline (servidor caído, mantenimiento, caída de la linea de Internet, etc) no perdamos ningún correo de los que nos envían.

Para ello simplemente nos damos de alta en el servicio con nuestro propio dominio y le decimos a Google Apps que comience a aceptar correo de nuestro dominio enviándoselo a una única cuenta de relay o backup.

Posteriormente nosotros, cuando el servidor primario vuelva a funcionar, comenzaremos haciendo un fecth de los correo.

Aquí tenéis toda la información necesaria: servidor_backup_googleapps.pdf

ocultando php

6 de septiembre de 2009

Hace algún tiempo escribí un post explicando los tres parámetros básico para ocultar el rastro de versión que dejaba Apache y PHP. Aun así, cualquier usuario podía saber si nuestra Web estaba escrita en PHP simplemente viendo que los archivos cargados de la Web terminaban en ".php".
Con ayuda del módulo mod_rewrite de Apache vamos a reescribir todas las URL de forma que el usuario no sepa en ningún momento que tipo de archivo está cargando. Nuestro objetivo es reescribir URLs como "http://miweb/index.php?id=123" por una URL como "http://miweb/index?id=123". Si el usuario quisiera cargar la página "index.php" debería producir un error de que la página no existe ya que realmente la que debe cargar es "index".

Los archivos que creemos no debemos quitarles el .php ya que esto será transparente para el programador Web.

Para crear estas reglas hay que crear un .htaccess en la raiz de nuestra Web o modificar la configuración general (el httpd.conf) de Apache.

RewriteEngine on

# Rescribe /carpeta/archivo.php por /carpeta/archivo
RewriteRule ^([^.?]+)$ %{REQUEST_URI}.php [L]

# Devuelve 404 si hacemos la petición /carpeta/archivo.php
# Para Apache en Windows utilizar esta condición. Para Linux no utilizar [NC]
# RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$" [NC]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

Más información:
- Apache mod_rewrite

los peligros del informador

27 de agosto de 2009

Una de las cosas que más gusta a un programador es saber en que servidor y que configuración por defecto tiene antes de empezar a programar su Web. Para los programadores de PHP tenemos una función muy bonita llamada phpinfo() que nos muestra una tabla colorida con toda la información de estado actual del motor de PHP, la versión del sistema Linux (o Windows), la ruta por defecto del php.ini, los módulos cargados del Apache, etc.

Muchas veces estas paginas quedan olvidadas dentro de nuestra aplicación Web a la espera que gente "despistada" las llame... nombres como hello.php, info.php e incluso phpinfo.php es lo normal.
Una búsqueda rápida en Yahoo o Google nos da una idea de los despistados programadores que han ido dejando sus pruebas.


La información que puedes encontrar en estas paginas es muy valiosa para la gente "con mucho tiempo libre", ya que puede encontrar números de versiones, módulos de Apache a los cuales poder atacar si existiera un bug, estado de los permisos de archivo o safe_mode o incluso en la variable path puedes encontrar otro tipo de software que corre en la maquina, como por ejemplo: NetBackups, tools de servidores Dell, antivirus, etc.

formularios php con muuu (parte ii de ii)

24 de agosto de 2009

muu posee diferentes tipos de datos que podrán utilizarse dentro de la función addField(). Estos pueden ser: text, textarea, password, select, radio o checkbox. Como vemos representan las estrucutas típicas de un formulario HTML.

Estos son algunos ejemplos:

$form->addField("text", "fecha", "Fecha de compra", array("instructions"=>"En 
       formato dd/mm/aaaa"));
$form->addField("checkbox", "vehiculo", "¿Qué vehiculo tienes?", 
       array("checkbixValues"=>array("moto"=>"Motocicleta","coche"=>"coche")));
$form->addField("select", "colores", "Seleccione un color", 
       array("selectValues"=>array("rojo"=>"Rojo","Azul"=>"Azul")));
$form->addField("radio", "sexo", "Sexo", 
       array("radioValues"=>array("hombre"=>"Hombre","mujer"=>"mujer")));
$form->addField("textarea", "opinion", "Su opinion");

Por otro lado, tambien tenemos un montón de tipos de reglas de validación. Veamos las más importantes:

- required: el campo no puede estar vacio.
- email: el campo debe ser una dirección de correo.
- emailorblank: el campo debe ser una dirección de correo o estar en blanco.
- rangelength: la longitud del campo debe estar dentro de un minlength y un maxlength
- equal: el valor del campo debe ser igual a otro valor
- lettersonly: el valor del campo debe tener solo letras
- aphanumeric: el valor del campo contiene letras y numeros
- numeric: el valor del campo contiene solo numeros
- maxvalue: el valor del campo no puede ser mayor del maxvalue
- minvalue: el valor del campo debe ser mayor que el minvalue
- float: el valor del campo debe ser un numero real
- integer: el valor del campo debe ser un numero entero
- ip: el valor del campo debe ser una dirección IP
- url: el valor del campo debe ser una dirección URL
- date: el valor del campo debe contener una fecha en formato dd/mm/aaaa.

Existen otras más y por si aun no se nos satisface nuestras necesidades siempre podemos utilizar la opción de regla "regex" que nos permite crear nuestra propia expresión regular para satisfacer nuestra propia regla de filtrado.

Veamos algunos ejemplos de estas reglas:
$form->addRule("required", "apellido", "El apellido no puede estar en blanco");
$form->addRule("date", "fecha_compra", "La fecha de compra no es correcta");
$form->addRule("rangelength", "password" , "La contraseña debe tener más de 3 
               caracteres", array("minlength"=>4,"maxlength"=>256) );
$form->addRule("equals", "clave", "Contraseñas diferentes", array("equalfield"=>"clave2"));

Para finalizar y una vez comprendido cómo funciona muuu, este es el código completo de una pagina de login desarrollada utilizando las librerías de muuu:
<?php
   include_once("muuu-v0.5.class.php");
   
   //--- campos de mi formulario
   $form= new muuu("form", "post", "login.php");
   $form->addField("text", "login", "Usuario: ", array("instructions"=>"(utiliza tú 
                   dirección de correo)") );
   $form->addField("password", "password", "Contraseña: ");
   $form->addField("submit", "boton", "", array("fieldAdd"=>"value='Enviar'"));

   //--- reglas de mi formulario
   $form->addRule("email", "login", "El nombre de usuario tiene que ser una 
                  direccion de correo válida.");
   $form->addRule("rangelength", "password" , "La contraseña debe tener más de 3 
                  caracteres", array("minlength"=>4,"maxlength"=>256) );
   
   if ( $form->formSuccess() == true ) {
      //--- procesamos los datos del formulario. En este caso se trata de una validación de usuario
      if ( $form->formValue("login")=="usuario@miempresa.com" &&
           $form->formValue("password")=="12345" )
         echo "Ok, estas dentro";
      else
         echo "Este usuario no es correcto";      
   } else {
      //--- arrancamos el formulario
      $form->startForm();
      echo "<fieldset>";
      echo "<legend>Inicio</legend>";
      //--- imprimimos el formulario
      foreach ( $form->fieldsarray as $key=>$value ) {
         echo "<p><label for='$key'>" . $form->labelsarray[$key] . "</label>$value</p>";
         echo "<p id='instructions'>" . $form->instructionsarray[$key] . "</p>";
         echo "<p id='error'>" . $form->errorarray[$key] . "</p>";   
      }
      echo "</fieldset>";
      $form->endForm();
   }
?>


formularios php con muuu (parte i de ii)

23 de agosto de 2009

Aunque suene a mugido de vaca española, "muuu" es una clase en PHP para facilitar a los programadores el desarrollo de formularios en PHP. Resulta muy pesado el escribir todo el código HTML del form, los campos, luego validarlos, repetir el campo si este no es correcto...

Para solucionar esto existe una librería libre llamada muuu que con dos funciones addField() y addRule() nos permite crear campos en nuestro formulario y lo más importante crear reglas que validen nuestro formulario. Para ver como funciona imaginemos que queremos una pagina PHP para validar a un usuario (una login.php). Con dos campos: nombre de usuario y contraseña. Como dos reglas, el nombre de usuario será una dirección de correo y la contraseña deberá tener más de 3 caracteres. Si no se cumple ninguna de estas reglas, el formulario no se procesa.

Lo primero que tenemos que hacer es cargar la librería, crear el formulario y añadir los campos que necesitamos (dos campos de texto y el botón de enviar):

   include_once("muuu-v0.5.class.php");
   $form= new muuu("form", "post", "login.php");
   $form->addField("text", "login", "Usuario: ", array("instructions"=>
                   "(utiliza tú dirección de correo)") );
   $form->addField("password", "password", "Contraseña: ");
   $form->addField("submit", "boton", "", array("fieldAdd"=>"value='Enviar'"));

Posteriormente debemos crear las reglas que deben cumplir nuestros campos. El usuario debe ser una dirección de correo electrónico y la contraseña debe tener más de 3 caracteres:
   $form->addRule("email", "login", "El nombre de usuario tiene que ser una 
                  direccion de correo válida.");
   $form->addRule("rangelength", "password" , "La contraseña debe tener más de 3 
                  caracteres", array("minlength"=>4,"maxlength"=>256) );

Una vez configurado nuestro formulario solo falta arrancarlo, imprimirlo en la Web y procesar el formulario si todos los campos han pasado las reglas:
   if ( $form->formSuccess() == true ) {
      //--- procesamos el formulario
   } else {
      //--- arrancamos el formulario
      $form->startForm();
      foreach ( $form->fieldsarray as $key=>$value ) {
         echo "<p><label for='$key'>" . $form->labelsarray[$key] . "</label>
              $value</p>";
         echo "<p id='instructions'>" . $form->instructionsarray[$key] . "</p>";
         echo "<p id='error'>" . $form->errorarray[$key] ."</p>";   
      }
      echo "</fieldset>";
      $form->endForm();
   }

El próximo post veremos el código completo de login.php

obtener todas las direcciones de correo

18 de agosto de 2009

La siguiente linea de comandos obtiene todas las direcciones de correo que aparecen dentro del log de Zimbra o cualquier otro archivo de log.

# sed -n -e '/postfix\/smtp\[.*status=sent/s/^.*to=<\([^>]*\).*$/\1/p' /var/log/zimbra.log | sort -u


hackeando el cristal glaseado con celo

7 de agosto de 2009



orden de preferencias en mysql

3 de agosto de 2009

En infomática por regla general la multiplicación y la división tienen preferencia sobre operaciones como la suma y la resta. Algo similar tambien sucede con operaciones lógicas como AND y OR. Las ANDs tienen preferencia sobre las OR. Una mala construcción de una consulta SQL nos puede jugar malas pasadas:

select true and false --> FALSE
select true or true and false --> TRUE

Esta característica se puede utilizar para saltarse mediante injección SQL paginas de login (en este caso PHP) que tengan una consulta así:
$sql = "
   SELECT * 
   FROM users 
   WHERE username='".$_POST["username"]."' AND password='".md5($_POST["psw"])."'";

Como vemos el campo password no es injectable ya que cualquier valor introducido es filtrado por una función. En este caso un hash md5.
El único parámetro injectable es username. Pongamos lo que pongamos en username siempre arrastraremos un "AND password=md5()" que por tanto deberá evaluarse.

Si tenemos en cuenta la prioridad en las operaciones AND/OR de MySQL podemos injectar con:
Username: ' or username<>'' or password<>'
Password: foo

La consulta SQL queda así:
SELECT * 
FROM users 
WHERE username='' or username<>'' or password<>'' 
      AND password='acbd18db4cc2f85cedef654fccc4a4d8'

La consulta siempre será evaluada a TRUE.