Wednesday, July 9, 2014

SQUID / No se puede acceder a Interjet

Antecedentes

Uno de los usuarios argumentó que no podía acceder a la pagina de Interjet. Este usuario utilizaba una pagina de convenio, la cual, al ingresar un código correctamente, redirecciona a una sección dentro de http://www.interjet.com.mx la cual todos los vuelos incluyen cierto  porcentaje de descuento.

Introducción

Ingresando al sitio de convenio con proxy, al rediccionar a Interjet, este manda a un sitio de nombre:
  • http://200.57.159.179/SorryPage/
El famoso "SorryPage" redirecciona a una pequeña sección de búsqueda de vuelos pero sin descuento.

Y cabe señalar que ingresando directamente al sitio de interjet con proxy redirecciona a esta misma sección de "SorryPage".

Por otro lado, ingresando al sitio de convenio sin proxy, este redirecciona correctamente a la sección de buscar vuelos con descuento, dentro del sitio web de Interjet.

Solución

Al ingresar a http://ww.interjet.com.mx, se puede apreciar que detecta el lenguaje del "User-Agent" (navegador) para desplegar sitio en el idioma y el país de compra. Lo cual no se me hace correcto, ya que es de lo más normal utilizar el navegador en otro idioma (sobre todo en Ingles).
Para esto, los programadores de Interjet hacen uso del request header "HTTP_ACCEPT_LANGUAGE".

Esto me hizo pensar en que estarían utilizando algún request header para filtrar el acceso.

Para saber que "request headers" manda SQUID, podemos utilizar un pequeño script de PHP el cual lea todos estos valores accediendo a el sin proxy y con proxy.

El sencillo script de PHP se muestra como:

// Leemos todos las variables del servidor
foreach ($_SERVER as $name => $value){ 
  if (substr($name, 0, 5) == 'HTTP_') 
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 
  }
// Imprimimos los resultados
var_dump($headers); 

El resultado de este script entrando desde Chrome sin proxy es:

array(8) {
  ["Accept"]=>
  string(74) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
  ["Accept-Encoding"]=>
  string(17) "gzip,deflate,sdch"
  ["Accept-Language"]=>
  string(45) "es-419,es;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2"
  ["Cache-Control"]=>
  string(9) "max-age=0"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Cookie"]=>
  string(58) "PHPSESSID=776d3499930de3eea3027f76d3bee0ba; __atuvc=2%7C25"
  ["Host"]=>
  string(16) "paralizabal.com"
  ["User-Agent"]=>
  string(109) "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
}

Y el resultado del mismo script desde Chrome pero con proxy es:

array(10) {
  ["Accept"]=>
  string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
  ["Accept-Encoding"]=>
  string(21) "identity,gzip,deflate"
  ["Accept-Language"]=>
  string(59) "es-MX,es-ES;q=0.8,es-AR;q=0.7,es;q=0.5,en-US;q=0.3,en;q=0.2"
  ["Cache-Control"]=>
  string(14) "max-age=259200"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Cookie"]=>
  string(172) "_ga=GA1.3.1925363739.1393444304; __utma=88164442.1925363739.1393444304.1399225959.1399482628.2; __utmz=88164442.1399225959.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)"
  ["Host"]=>
  string(16) "paralizabal.com"
  ["User-Agent"]=>
  string(72) "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0"
  ["X-Forwarded-For"]=>
  string(7) "192.168.1.100"
}

Con esto podemos apreciar que la diferencia es el encabezado "X-Forwarded-For", el cual indica la IP original del cliente conectado a un servidor web mediante un HTTP-Proxy o Load balancer, estándar sugerido, precisamente, por los desarrolladores de SQUID.

 Así que la solución final es deshabilidar este encabezado en SQUID, de forma muy sencilla, agregamos en el archivo squid.conf la siguiente línea:

forwarded_for on

Reiniciamos SQUID y listo!, podemos entrar al sitio principal de http://ww.interjet.com.mx.

Friday, July 4, 2014

Dado un string, analizarlo y convertirlo a palindrome en caso que sea posible

Antecedentes

En una entrevista de trabajo me pidieron realizar la siguiente actividad: "Desarrollar una función la cual recibirá un string, analizarlo y tratar de convertirlo a palindrome". No precisamente el string estará en el mismo orden, por ejemplo, la función puede recibir ->  SSUUG la cual en su versión palindrome sería SUGUS.

Introducción

El error que cometí fue el estar pensando en el detalle de las posibles combinaciones, en mi mente estaba:

Posibilidades de crear una palabra palindrome dependiendo su longitud

2 -> 2
3 -> 2-1
4 -> 4, 2-2
5 -> 2-2-1
6 -> 6, 4-2, 2-2-2
7 -> 6-1, 4-2-1, 2-2-2-1
8 -> 8, 6-2, 4-4, 4-2-2, 2-2-2-2
9 -> 8-1, 6-2-1, 4-4-1, 4-2-2-1, 2-2-2-2-1
10 -> 10, 8-2, 6-4, 4-4-2, 4-2-2-2-2, 2-2-2-2-2

Por lo que después de haber creado la función en base a la lógica más complicada, pensé en lo que el entrevistador me dijo al final: "Solo puede haber un fallo".

En efecto, las letras se deben presentar en pares y si se tiene 2 letras individuales diferentes, no es posible convertirla a palindrome.

Solución

La solución queda detallada de la siguiente forma:

1.- Crear un array con las letras únicas y las veces en que se repite (desde aquí se puede hacer la validación de palindrome pero yo decidí hacerlo en el paso #2).
2.- Imprimir las palabras del array en forma palindrome.

El código en javascript se ve así:




Y aquí un pequeño demo:

Thursday, June 5, 2014

Modificar archivo class de un jar sin tener el código fuente

Antecedentes


La empresa para la que trabajo realizó una activación en el estadio Omnilife, la cual tomaba fotografías con una "Samsung Galaxy Camera (Jelly Bean 4.1)", esta cámara recibía señal para el "shooting" desde una tablet "Galaxy Tab 3 (Jelly Bean 4.1)". La logística y desarrollo tecnológico lo realizó un proveedor, una de las herramientas que desarrollaron fue un "uploader" en JAVA, el cual conectaba con un pequeño webservice para tener las fotografías en un micrositio. 
El problema se presentó al tener 2 activaciones al mismo tiempo, que se verían reflejadas en 2 micrositios diferentes, por lo que se debía actualizar la ruta del webservice. Esto representaba cambiar un par de lineas de código pero el problema real era no contar con el código fuente, solo con el jar.

Introducción

El archivo JAR no es más que un zip, por lo que podemos consultar su contenido, ver su estructura, imágenes, paquetes, clases (esto último compilado) con tan solo cambiar la extensión de "jar" a "zip".

Solución

Entendiendo esto, lo que debemos hacer es:
  1. Decompilar el JAR.
  2. Guardar clase como ".java"
  3. Modificar las clases
  4. Compilar ".java"
  5. Actualizar ".class"

1.- Decompilar JAR

Una de las mejores herramientas para decompilar es "Java Decompiler" desarrollada por Emmanuel Dupuy, la cual esta disponible en 4 diferentes sabores: GUI (mi elección), Eclipse,  IntelliJ y Live Demo.
  •  Ejecutamos Java Decompiler -> Nos vamos al menú "Archivo" -> Abrir archivo -> Buscamos nuestro JAR. 
2.- Guardar clase

El programa nos muestra el código reconstruido, con esto podemos copiar toda la clase y pegarla en un nuevo archivo de texto nombre "nombreArchivo.java" y guardarlo en la misma ubicación de nuestro archivo JAR.

3.- Modificar clase


Hacemos las modificaciones de código correspondientes en nuestro archivo "java".

4.- Compilar ".java" (jarc command)

Nota: Muy importante, recomiendo colocar en la carpeta "C:\Program Files\Java\jdk1.7.0_XX\bin", los tres archivo: "jar", "java", "class". Ya que el comando "jar.exe" (que veremos en el siguiente punto) crea el archivo, dentro del jar, con la misma ruta de nuestra ubicación física.

   A) Ejecutamos la consola de windows con permisos de administrador.
   B) Nos movemos a la ubicación del "javac.exe" (c:\Program Files\Java\jdk1.7.0_XX\bin)
   C) Corremos el siguiente comando: javac -classpath nombreArchivo.jar nombreArchivo.java

5.- Actualizar ".class" (jar command)

Por último, para actualizar la clase, utilizamos el comando "jar" de java, por lo que:

   A) Ejecutamos el comando: jar uf nombreArchivo.jar nombreArchivo.class

Listo, hemos modificado código de una JAR, sin tener los fuentes.

 Referencias

  • http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html
  • http://docs.oracle.com/javase/tutorial/deployment/jar/update.html





Monday, May 5, 2014

CentOS 6 / Squid - No carga sitios que soportan ipv6

Antecedentes
Squid

Momento en el que uno se convierte en el villano de los usuarios: cuando bloqueas las redes sociales. Efectivamente, me solicitaron volver a activar el bloqueo de ciertos sitios de entretenimiento por horarios y usuarios, pero esta vez squid se comportaba de forma extraña, todos aquellos sitios que soportan ipv6 no eran cargados, por ejemplo:

 - https://www.facebook.com
 - https://www.yahoo.com
 - https://www.ipv6ready.org

Introducción

Mi configuración inicial es:
- CentOS 6.5 i686
- Squid 3.4.3
- Dansguardian 2.10.1.1

De acuerdo a la documentación de squid soporta ipv6 desde la versión 3.1.x, teniendo que agregar ciertos parámetros (en "squid.conf") para la serie de versiones (3.1.x), no así para las versiones superiores, están ya vienen integradas, siempre y cuando se compile con "--enable-ipv6".

Yo contaba con la versión de squid 3.1.10, la cual tiene documentado bugs con ipv6, por lo que decidí actualizarme a la versión 3.4.3 (23/Abril/2014).
Después de actualizar y ajustar los parámetros de "/etc/squid/squid.conf" a la nueva versión, seguía teniendo problemas para abrir sitios que soportarán ipv6, este era el síntoma en los registros:

Comando:
  - # squidclient https://www.facebook.com
       - Sending HTTP request

  - # squidclient https://www.yahoo.com
       - Sending HTTP request

Registros ("/var/log/squid/access.log"):
-TCP_MISS/301 2664 GET https://www.facebook.com - HIER_DIRECT / 2a03:2880:f00b:800:face:b00c:0:1
-TCP_MISS/301 713 GET https://www.yahoo.com:443 - HIER_DIRECT / 2001:4998:44:4:c:9102

-TCP_MISS_ABORTED/000 0 GET https://www.facebook.com - HIER_DIRECT / 2a03:2880:f00b:800:face:b00c:0:1
TCP_MISS_ABORTED/000 0 GET https://www.yahoo.com - HIER_DIRECT / 2001:4998:44:4:c:9102

Solución

La solución en muchos foros, era: "deshabilita ivp6 del squid y de tu CentOS", "Crea un puerto para HTTP y otro para HTTPS", esto no es nada recomendable en la documentación oficial.

La solución la encontré en uno de los parámetros de "squid.conf", el cual está por default en "off":

 -  dns_v4_first on

Reincias squid y "voilà", no más TCP_MISS_ABORTED para sitios que soportan ipv6.

Referencia: http://www.squid-cache.org/Doc/config/dns_v4_first/

Wednesday, April 30, 2014

¿Por qué no puedo entrar al IDSE utilizando Chrome o Firefox?

Antecedentes

En la empresa para la que trabajo, uno de módulos del ERP que desarrollamos, genera archivos en txt para dar altas y bajas del personal de campo y una de las preguntas más comunes de los encargados de esta actividad es: "¿Por qué no puedo acceder al IDSE utilizando Chrome o Firefox?




Introducción

Dos de los navegadores más utilizados en la actualidad son Google Chrome y Mozilla Firefox, por lo que es habitual que se intente acceder al IDSE utilizando uno de estos.


Solución

Respuesta corta: 

  - Los desarrolladores del IDSE no han actualizado el código para cumplir con los nuevos (desde el 2002) lineamientos de seguridad.

Respuesta larga:

   - Vamos a revisar el código para encontrar el problema.

Dentro de la pagina del IDSE, al dar click en el botón "iniciar sesión", manda a llamar la función de javascript "Sing()", la cual en su sexta línea de código contiene:

var pkcs12 = document.firmaForm.certificado.value;


Esto quiere decir que la variable "pkcs12" contiene el nombre del certificado que seleccionamos en el input "certificado digital".

Hacemos un paréntesis en este punto, para recordar que unos de los pasos para acceder a IDSE con Internet Explorer es habilitar la opción "Incluir el directorio local cuando se suban archivo al servidor". Esto hace que la ruta de nuestro archivo se muestre como (igual que el valor de la variable "pckcs12"):

  - Internet Explorer - "C:\Usuarios\UsuarioA\Desktop\certificadoIMSS.pfx"

Por cuestiones de seguridad Chrome/Firefox no incluyen la ruta completa (me parece bastante razonable), dándole a la variable "pckcs12" el valor de:

 - Firefox - "certificadoIMSS.pfx"
 - Chrome - "C:\fakepath\certificadoIMSS.pfx"

Teniendo en cuenta esto, si tratamos de iniciar sesión nos mostrará el error:

 - "El archivo no existe o se modificó la ruta del archivo. Por favor verifique y actualice la información".

Continuamos con nuestro análisis hasta llegar a la línea 371 de uno de los applets, la cual dice:

FileInputStream localFileInputStream = new FileInputStream(paramFile);

Esta línea trata de obtener los bytes del certificado (paramFile=pckcs12) y debido a que Chrome/Firefox no incluyen la ruta absoluta, devuelve el error antes mencionado (no encuentra el archivo en la computadora del cliente).

Soluciones

Algunas de las soluciones son:

1.- Que los desarrolladores actualicen el código / La mejor opción
* La mejor pero menos probable (por los cambios que implica) es que se actualice la forma en que se realiza el "login" en el sistema IDSE, el sistema debe subir el certificado al servidor o crear un nuevo applet para "login" y así poder seleccionar al archivo desde java (no por javascript).

2.- Instalar el complemento IETab.net en Chrome / Probable
* Este complemento es un emulador de Internet Explorer, que tiene habilitada por default la opción para incluir la ruta absoluta de los archivos.

3.- Seguir utilizando Internet Explorer / No recomendable
* Con todos los problemas de seguridad no es recomendable seguir utilizando este navegador.

4.- Crear el directorio C:\fakepath / Chistoso - No recomendable
* Creando el directorio mencionado y agregando a esa ruta el certificado, Chrome pasará la ruta absoluta utilizando el "fakepath" por lo que el applet encontrará el archivo.

Thursday, November 14, 2013

Adminpaq Error 42501 al ejectuar la terminal en un usuario limitado

Antecedentes


Una pequeña empresa me contactó para apoyarla, entre otras cosas, con la configuración de Adminpaq para que corriera en sesiones con usuarios limitados y la primer palabra que se me vino a la mente al escuchar "Adminpaq" fue "problema".


Introducción

Es ampliamente conocido que lo primero que se debe hacer es darle permisos a los usuarios en el registro de windows para la entrada "Computación en Acción" y sus subentradas, esto es en:
  • HKEY_LOCAL_MACHINE -> SOFTWARE -> Computación en Acción, SA CV
Después de asignar los permisos mencionados intenté entrar y "cuack" error 42501

Leyendo el buscador de conocimientos en la pagina oficial me encontré con que:
  • DAR PERMISOS AL USUARIO DE WINDOWS EN EL REGEDIT O INGRESAR CON UN USUARIO CON DERECHOS DE ADMINISTRADOR
¿Dar permisos al usuario de windows en el regedit?, ¿A todo el registro ó a cuales entradas? ... ¿O ingresar con un usuario con derechos de administrador? mmmm ¿Y donde esta la solución real a mi problema?

Solución

Después revisar los permisos en el registro, firewall, variables de entorno, encontré la solución en: dar permisos al usuario en la carpeta de instalación "Adminpaq".

Finalmente, entrando con un usuario administrador, nos vamos a:
  1. C -> Archivos de Programa -> Compacw 
  2. Click con el botón derecho en "Adminpaq" -> propiedades -> pestaña seguridad
  3. Buscamos/agregamos y seleccionamos a "Usuarios" -> click en "Control Total"
  4. Aceptar
Listo!, podemos entrar a Adminpaq con un usuario limitado.



Wednesday, October 9, 2013

Comprar una laptop Dell por internet

Antecedentes


Decidí adquirir una laptop para empezar a trabajar en varios proyectos personales, pienso que el primer paso para seleccionar de mejor forma el equipo, con el que vas a trabajar por varios años, es leer reseñas en internet de los mejores portatiles en cuestión precio/rendimiento.

Por lo que todo (en ese momento) apuntó a una Ultrabook Dell 14z, no es una Alienware pero para las funciones que tengo pensadas realizas está bastante cumplidora.

Hace más de 4 años tuve la oportunidad de adquirir para una empresa una Dell XPS 13, la cual me gustó bastante pero tardó más del mes en llegar al domicilio. Pensé que esto pudiera haber cambiado dramáticamente y que Dell iba a tener una bodega en México para solo realizar envío nacional en cuanto se confirmara la compra (para equipos no configurables a nivel hardware) ... esto era solo un "tal vez".

Proceso de compra

Después de elegir el modelo en el sitio Dell, el cual no era configurable a nivel hardware, procedí a realizar el pago con tarjeta de crédito y llegar hasta el punto de finalizar la compra sin mayor problemas, concluyendo con un correo de "confirmación de orden" por Dell el 18/Sep/2013.

La intriga sobre el status de mi equipo me llevó a consultar cada 2 hrs mi cuenta en la pagina Dell, está sin presentar algún cambio hasta el 20/Sep/2013, fecha en la que recibí dos correos; uno de "mi ejecutivo" y otro de "confirmación de compra" que fue cuando me dí cuenta que apenas se había realizado el cargo a la tarjeta de crédito.

Ese último correo también trae un link a la plataforma de Dell para monitorear el proceso de tu pedido, dividido en:
  1. Procesamiento de pedidos.
  2. Previo a la producción.
  3. En producción.
  4. Enviado.

Este correo también fue el inicio de una laaaaarga espera y angustia de saber "¿Cuando tendré el equipo en mis manos?" y fue hasta el 1/Oct/2013 cuando apareció en la plataforma el nombre del transportista "KUEHNE NAGEL" y un número de guía para rastrear el envío. El sistema de esta compañia mostraba que la guia no era correcta por un lapso de 3 días, hasta que por fin el 4/Oct/2013 desplegó información acerca del envío, la cual decía que la "fecha de estimada" de entrega sería el 9/Oct/2013.

Traté de mantener la calma y no consultar la pagina de Dell/Kuehne+Nagel cada hora y fue el 7/Oct/2013 cuando recibí otro correo de Dell informandome mi número de guía el cual podría rastrear por Estafeta, si, por Estafeta y fue cuando me di cuenta que Kuehne+Nagel entrega en México y Estafeta distribuye a su destino final.

Así que ahora con Estafeta como tercera compañía encargada de entregar mi pedido, tuve cierta tranquilidad de saber que por lo menos "esta fluyendo" y con el tipo de envío "garantizado al tercer día hábil", supe que mi equipo estaría llegando a mis manos el 8 o 9/Oct/2013.

"Dicho y hecho", el miercoles 9/Oct/2013 recibí mi nuevo equipo de trabajo.

En resumen

Como lo mencioné en el tercer párrafo; pensé que el tiempo de entrega había mejorado con el paso de los años y sobre todo para los equipos no configurables a nivel hardware pero desafortunadamente no fue así:

  • Tiempo de entrega: 22 días totales o 16 días hábiles.