2013-05-03

Debugueando en root con pydev

Quiero poder debuguear cosas que estoy desarrollando y requieren root. Para eso, me hice un pequeño wrapper que sirve para ejecutar cualquier programa de python y se conecta a un pydevd server

#!/usr/bin/env bash
PYDEVD_LOCATION=/home/aure/Aptana_Studio_3/plugins/org.python.pydev_2.7.0.2013032300/pysrc
export PYTHONPATH=$PYDEVD_LOCATION:$PYTHONPATH
echo PYTHONPATH=$PYTHONPATH
python $PYTHONARGS -c "import pydevd;pydevd.settrace(suspend=False,trace_only_current_thread=False);import sys;print sys.argv;sys.argv=sys.argv[1:];print sys.argv;execfile(sys.argv[0])" $@


Para usarlo, copienlo en un archivo ejecutable que esté en el path y cambien PYDEVD_LOCATION para que apunte a dónde tienen pydev (en el script de arriba está como es en mi compu).

A partir de ahora puedo debuguear en root haciendo sudo pydevd my_script_que_corre_como_root.py y lo abre en el debugger de eclipse.

Happy hacking,
Aureliano.

2013-04-04

Invalid private key

Poner un certificado nuevo en un ELB debería ser fácil, pero no. Genero un .csr y una clave privada a partir de un .conf usando openssl, lo mando a la autoridad certificante y cuando lo quiero subir a AWS se queja, "Invalid private key".  ¿Qué carajo te pasa AWS?

Lo que pasa es que es hincha bolas. Solo toma claves RSA. Si tu clave privada empieza así:
-----BEGIN PRIVATE KEY-----

Hay que transformarla en una que empiece así:
-----BEGIN RSA PRIVATE KEY-----

Para eso, hay que correr un comandito en openssl:
openssl rsa -in my.private.key -text

La salida está en el formato que necesito :D. Por suerte esto ya lo habían descubierto antes, porque sino hubiera estado mucho más tiempo para encontrarlo.

Happy hacking,
Aureliano.

2013-03-29

Cambiando el MTU

Por algún motivo, mi conexión wifi está dropeando paquetes. No creo que sea el aparato, ya que probé con 2 distintos. Ahora voy a probar otra cosa. Lo que voy a hacer es cambiar el MTU (o sea el tamaño máximo de cada paquete) para la conexión wifi para ver si eso lo arregla.

Hacer eso en Windows 7 es re-oscuro. Googleando encontré acá cómo hacerlo. Dejo las instrucciones abajo para que quede claro:


  1. Abrí un cmd cómo Administrator (botón derecho en Todos los Programas > Accessorios > Símbolo de Sistema y elegí Ejecutar como administrador) ...
  2. Escribí netsh y esperá el prompt
  3. Escribí interface y esperá el prompt
  4. Escribí ipv4 y esperá el prompt
  5. Escribí show interfaces y fijate cuál es la conexión que querés tocar (en mi compu fue Conexión de red inalámbrica)
  6. Escribí set subinterface "Aca va el nombre de la conexion que queres cambiar" mtu=1400 store=persistent
Creo que eso arregla el problema.

Happy hacking,
Aureliano.

2013-03-27

Línea de comando svn por proxy http

Para salir a través de un proxy usando la línea de comando de svn hay que cambiar la configuración del cliente de svn. Una opción es ir a tocar el archivo ~/.subversion/servers, otra opción es pasarle por línea de comando host y port del proxy así:

svn --config-option servers:global:http-proxy-host=the.proxy.server --config-option servers:global:http-proxy-port=3128  checkout http://some.svn/repo

Happy hacking!

2013-03-19

¿Cómo cierro conexiones nesteadas de ssh?

Cuando una conexión de ssh se caga, para poder seguir usando la terminal hay que hacer: ENTER ~. ENTER y la conexión de ssh se corta.

El problema es que no sé como hacer para hacer algo similar para una conexión nesteada.

Desde mi workstation me ssheo al host A y desde el host A al B.

Las conexiones quedan así:

W ----ssh-----> A ------ssh-----> B

Y por algún motivo se caga la conexión entre A y B, todo el quilombo queda así:

W ----ssh-----> A --ssh(cagó)---> B

Para romper la conexión entre A y B hay que hacer: ENTER ~~. ENTER

El ñuflo extra es para escapar el ~ de la primera conexión y que le llegue a la segunda.

Happy hacking!

2013-02-21

gnome-terminal y keepass2

Keepass2 en Linux (corriéndolo con mono), pone el password en un clipboard (cuando hacés Ctrl-C)  que gnome-terminal no usa por default (mirando con xset, lo pone en el clipboard "clipboard", pero no en el "secondary"). Por lo tanto, no anda ni CTRL-V ni el menú para hacer paste del password (o el usuario) sacado de keepass2. Este problema lo vi en Linux Mint, pero debería darse en cualquier interacción entre mono y gnome-terminal.

Workarounds:

  1. Extrañamente, CTRL-SHIFT-INSERT sí pega las cosas que pusiste en el clipboard con keepass2 (fuente: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=645200).
  2. Drag-and-drop de keepass2 a la gnome-terminal correspondiente.
Happy hacking,
Aureliano.

2013-02-03

Bug Brother's Design Rules


  • War is Peace: assume you are at war, all input is an attack, and then you can be at peace.
  • Slavery is Freedom: the more you constrain your code's behavior, the more freedom you have to act. The smaller your interface, the smaller your attack surface.
  • Ignorance is Strength: the less your code knows about, the fewer things it can break. This is the principle of least authority.

2013-02-02

Manejo de passwords

La vida me transformó en un devop por un rato, así que estoy teniendo algunos problemas de sysadmin. Entre ellos, estoy buscando un buen sistema de manejo de passwords. Hay passwords que son sólo míos (muejeje!) y passwords que tenemos que tener varias personas. Por último, estaría bueno tener acceso a esos passwords desde varias compus.

Para tener los passwords en una sola compu, keepass o password safe están bien. Para manejar los passwords que uso por la web, last pass parece estar bueno, pero ¿puedo tener passwords que uso en la línea de comando? (ejemplo, claves para desencriptar archivos .pem).

¿Pero, cómo hago para compartir algunos de estos passwords con otras personas? La solución que se nos ocurrió en el laburo es meter el archivo de keepass en el control de versiones (svn). Los problemas de esto es que si por algún motivo hay un conflicto, la resolución es un quilombo y que tener derecho más granulares sobre los passwords no parece algo fácil (¿diferentes archivos de keepass, con diferentes passwords, en función del dominio de seguridad?).

¿Alguien probó last pass premium? (que permite compartir passwords)

¿Alguna otra sugerencia?

Happy hacking,
Aureliano.

2012-12-27

Cómo convencerme de que las cartas natales funcionan

Update: Parece que hicieron un estudio parecido al que yo propongo en la década del 80, y los resultados no fueron nada alentadores para los defensores de la astrología.

Ayer estaba charlando y se me ocurrió un experimento que se puede hacer para validar o refutar que las cartas natales funcionan.
Ingredientes:

  • Varias personas que sepan hacer e interpretar cartas natales (que llamaré "adivinos").
  • Varias personas que estén dispuestas a no revelar su fecha y lugar de nacimiento en una entrevista con un adivino (que llamaré "cobayos").
Mecanismo:
  1. Los cobayos son divididos en 2 grupos que tienen igual cantidad de miembros, los "mentirosos" que son aquellos a los que se les cambia levemente la fecha de nacimiento (+- 1 semana) y los "realistas", a los que se les deja la fecha de nacimiento como es. Cada cobayo no sabe si es realista o mentiroso.
  2. Cada adivino es asignado con la misma cantidad de mentirosos y realistas, y usando la información de momento y lugar de nacimiento (que está mal solo para los mentirosos) prepara las cartas natales de cada cobayo.
  3. Los adivinos se reúnen con cada uno de sus cobayos individualmente y tienen una charla de una hora. En esa charla está prohibido que hablen de la fecha exacta o lugar exacto de nacimiento del cobayo. El objectivo de la charla es que el adivino pueda establecer si la fecha y lugar de nacimiento que le dieron del cobayo es correcta o no, viendo si el mismo "matchea" con la carta natal que preparó.
  4. Después de terminar cada entrevista, cada adivino deja escrito si piensa que el cobayo es mentiroso o realista.
  5. Por último, teniendo todas las respuestas de los adivinos, hacemos un test de significación estadística para ver si los adivinos son efectivos distinguiendo a los realistas de los mentirosos.
Si el test estadístico dice que hay diferencias significativas, entonces voy a empezar a creer en esas cartas natales. Mientras tanto, y siguiendo el principio de la navaja de Occam, voy a seguir creyendo que son una paparruchada. 

Happy hacking,
Aureliano.

PD: Tarea para el hogar, diseñar un test parecido para el horóscopo.

2012-12-01

Comida fácil de preparar: Hoy, berenjenas a la plancha.

  1. Prenda el fuego y ponga la plancha encima
  2. Lave una berenjena y córtela en rodajas de aproximadamente 4 milímetros
  3. Ponga las rodajas en la plancha y tíreles un chorrito de aceite de oliva
  4. Espere 5 minutos y délas vuelta.
  5. Espere 5 minutos y apague el fuego
  6. Sirva en un plato.


2012-11-27

Cómo empecé a hacer stand up

El otro día fui a ver a un amigo a hacer standup y eso me inspiró para escribir un monologuito sobre algunos aspectos del tango como baile social. Cualquier parecido o divergencia con la realidad es pura coincidencia. El título del mismo es "Cómo empecé a hacer stand up"

Hola,
yo soy Aureliano, sí mis viejos me la hicieron complicada, y bailo tango.

Ustedes se preguntaran como puede ser que baile tango. (con voz de viejo todo encorvado) No tengo 80 años, soy carilindo (guiño de ojos), parezco un cantante de glam de la década del 80, o me parezco a Jesús (peinado a 2 aguas mientras miro el piso, cuando termino miro al público).

Bueno, ¿cuántos de ustedes bailan tango? (Mirando al público)

Veo que no hay nadie (o hay muy poquitos) que saben bailar tango acá. Pensé que estábamos en la cuna del tango, donde nació Gardel, donde compusieron la Cumparsita, donde se ponía en pedo Piazzolla (pausa). Buenos Aires es la cuna del tango. Bueno, les voy a contar un poco como funciona todo esto porque sino no van a entender ningún chiste.

El baile del tango viene en dos sabores, escenario y salón. El tango escenario es el que pueden ver en un teatro, o en Caminito un domingo al mediodía. Una o más parejas haciendo piruetas.  Los chabones, (reflexionando) ¿chabón si que es una palabra tanguera, no?, los chabones disfrazados de muñeco de torta, con una flor roja en el ojal. Las minas con medias de red y un vestido largo rojo con un tajo al costado (señalo con el brazo opuesto haciendo el recorrido del tajo) que les llega hasta la axila. Bueno (pausa), yo no hago eso.

Lo mío es el tango salón, o tango social. Ese tango es el tango que bailaban nuestros abuelos, rechazaron nuestros padres. Se baila en unos lugares que se llaman milongas. Yo tengo identificados tres circuitos en los que clasifico a las milongas.

El primero es el turístico, es el que más conoce la gente que no baila. Suelen ser milongas que están por el centro. Hay principalmente turistas de todo origen, edad, sexo, nivel de baile y peso.También hay argentinos tratando de rapiñar algo, ¡cuándo no!. Hay profesores y profesoras de tango buscando alumnos, gente que alquila alojamiento, taxi-dancers, que son algo así como las putas del baile. Algún o alguna patadura no quiere planchar en la milonga y le paga a un bailarín o bailarina para que los baile. Y, como no, siempre hay alguien en busca de sexo ocasional (cara de inocente) y/o un viajecito a Europa desde arriba.

El segundo circuito es el de las milongas de viejos. Éstas abren generalmente más temprano y son en lugares como el Cuartel de Bomberos Voluntarios de Lanús. Estas milongas son extrañas. No hay nada más bizarro que ver a una señora de la edad de tu abuela vestida con un traje de leopardo pegado al cuerpo, al lado otra que está con una minifalda y con ellas una tercera que en un traje largo parece un matambre. Acá no van a encontrar ni un turista.

Por último está el circuito joven. Aunque su epicentro está por Palermo, también es fuerte por la zona de San Telmo. Hay un montón de turistas en este circuito, y también un montón de argentinos y argentinas, y, como dice el nombre, acá vienen el grueso de la gente de menos de 40. Este circuito se caracteriza por la violencia de las patadas que se propinan en la pista. Por ejemplo el otro día presencié como una mina tiró un voleo alto y cortó el muslo de otra mina con el taco aguja.

En cualquiera de los circuitos funciona el cabeceo. El mismo consiste en hacer un movimiento en diagonal ascendente apuntando hacia la pista mientras estableces contacto visual con una mina (mirar a alguien del público y hacer el movimiento lentamente). Si la mina está de acuerdo con la invitación asiente con la cabeza y espera a que la vaya a buscar. ¡Chicas! no se levanten directamente que si el cabeceo no es para ustedes es un bochorno.

Te acercás a la pista, y muchas veces sin mediar una sola palabra, te fundís en un abrazo. Esto es de lo más lindo del tango, y un tanguero que se precie puede, solo con ese abrazo, saber muchas cosas de la mina con la que está. ¿Estás nerviosa? ¿Está triste? ¿Se bañó? ¿Tiene las tetas operadas? (gesto de tetas con las manos, pausa). Podés saber todo eso antes de saber como se llama.

En las milongas se bailan grupos de 4 tangos, que se llaman tandas y que están separados entre sí por una canción no bailable, que se llama cortina. Una vez que termina la tanda, todos se van de la pista.

Entre tango y tango, dentro de una tanda, la pareja de bailarines tiene unos 20 segundos para tener una pequeña charla. Y, la verdad, nunca supe bien qué decir en esos momentos. Sí les puedo contar que intenté.

Yo: Qué linda tanda
Ella: qué orquesta es?
Yo: ni idea (cara de :-\ )

Yo: "La milonga está re-llena"
Ella: Y?
Yo: (cara de y en donde me meto)

Yo: "La milonga está re-llena"
Ella: Me estás diciendo gorda?

Yo. De dónde sos?
Ella. Eurasia.
Yo. Y eso qué es?

También probé no decir nada. A veces está todo bien, pero no siempre. Es especialmente malo cuando el disk jockey tarda en poner el siguiente tango. Son 5, 10 o 20 segundos fatales. De mirarse sin decir nada.

Lo peor, para mi, es preguntar el nombre de mi bailarina.

Yo: Cómo te llamas? (cara de langa)
Ella: Ya es la cuarta de vez que me preguntás mi nombre.
Yo: ups
Ella: Y a una amigas ya le preguntaste 2 veces
Yo: (hago un pozo con una pala y me entierro)

Aunque a veces zafo un poco más.

Yo: Dejé de preguntar nombres porque siempre me olvido.
Ella: Yo siempre me olvido también. ¿Cómo te llamás?
Yo: Aureliano.
Ella: Mi nombre también es complicado.
Yo: ¿Cómo es?
Ella: Emanuela
Yo: Mi segundo nombre es Emanuel
Ella: ¡Me parece que ya tuvimos esta conversación alguna vez!
Yo: ¡Esto lo voy a poner textual en el monólogo que estoy escribiendo!

Una cosa que me funcionó llamativamente bien es decir "no sé qué decir entre tango y tango", el problema es que como ahora sé que decir, ahora no sé qué decir y ahora que no sé qué decir sé que decir. ¡Bertrand Russell estaría orgulloso de mi!

Y reflexionando sobre esto me di cuenta que de da para hacer de esto un guión y así empecé a hacer standup.

2012-09-12

Blogpost explicando mi paper

Publicaron en el blog de Core un artículo donde explico qué es esto del crackeo confidencial de passwords (en inglés). El paper, "Oblivious password cracking", lo había anunciado en este post.

Happy hacking,
Aureliano.


2012-09-04

Paper publicado

El viernes presenté el paper del que les conté hace unos meses, "An Oblivious Password Cracking Server" en el 4to Workshop de Seguridad Informática, parte de 41va JAIIO.

Salió todo buenísimo, y están disponibles el paper y los slides en la página de CoreLabs.

Happy hacking,
Aureliano.

2012-08-09

Inutilizando el caching de contenido estático en tornado

Update: El setting debug=True hace que se recargue todo lo que puede ser recargado. Creo que este hack no hace falta.

Este pequeño método deja sin efecto el cache de contenido estático de tornado.

def debug_hacks():

    from tornado.web import StaticFileHandler
    import time
   
    StaticFileHandler.CACHE_MAX_AGE = 0.1 #caches 0.1 seconds

    def clean_hash_cache():
        while True:
            StaticFileHandler.reset()
            time.sleep(0.1)
           
    clean_thread = threading.Thread(target=clean_hash_cache)
    clean_thread.daemon = True
    clean_thread.start()

Hay que ejecutarlo antes de arrancar tornado para que sirva.

Happy hacking,
Aureliano.

2012-07-20

IMEI de tu celular

Discá *#06# en tu TE y aparece tu número de IMEI. Esto está en el standard de GSM (o sea, debería andar en todos los celulares de Argentina, salvo Nextel).

Happy hacking,
Aureliano.


2012-07-18

Subclipse

Si quieren configurar subclipse en windows sigan estas instrucciones.

Happy hacking,
Aure.

2012-07-10

Haciendo cerveza - Día 2

Ya pasaron 2 semanas desde que pusiste todo a fermentar. Abrís el fermentador y tiene olor a cerveza. ¿Y ahora qué?

Ya falta poco. Desinfectamos las botellas, las tapas, una de las ollas con canilla y una manguera. Preparamos la tapadora. Diluímos el azucar en agua sin cloro (8g por litro de cerveza). Tiramos el agua azucarada en el fermentador y pasamos todo el contenido del fermentador a la olla que desinfectamos hace un ratito.

Enchufamos la manguera en la canilla y llenamos las botellas, dejando el cuello sin llenar para que la presión del gas no haga quilombo. Y las tapamos.

Felicitaciones, las botellas están listas. Ahora hay que esperar 2 semanas con las botellas a temperatura ambiente para que se forme el gas y se termine de asentar el gusto de la cerveza. Una vez pasadas las 2 semanas, podés meter las botellas en la heladera y disfrutar de la riquísima cerveza que hiciste vos mismo.

Happy hacking,
Aureliano.

2012-06-25

Paper aceptado

Aceptaron el paper "An Oblivious Password Cracking Server" en el 
4to Workshop de Seguridad Informática (WSegI) de la JAIIO.

Cuando lo presente mando más data por acá,
Aureliano.

2012-06-09

Haciendo cerveza - Día 1

Preparativos

Asegurate de tener todo lo que necesitás para hacer cerveza. El día anterior, agarrá 60 litros de agua de la canilla y dejala evaporar en las ollas para que se desclore.

Haciendo el mosto

Vas a hacer el "té" más grande de tu vida. Poné en la olla el filtro (o sea la tela) y adentro de ella toda la malta molida (la del kit). Agregá 30 litros (más o menos) del agua desclorada y prendé el fuego. Llevá la temperatura a 65 grados y mantenela ahí por una hora. Si tiene menos de 60 grados o más de 70 la cagaste. Chequeá con el termómetro que estés siempre en el rango de temperaturas correcto. A este proceso se le llama "conversión de azúcares". ¿Ya pasó una hora? Apagá el fuego y, usando la canilla del fondo de la olla, pasá la infusión que te queda a otra olla. Esa infusión se llama "mosto". 
Hay 2 cosas que podés hacer en este paso para obtener más cerveza. Una opción es recircular el mosto poniéndolo de nuevo en la olla que tiene la malta, extrayendo un líquido más denso. La otra, es agregar agua (acordate que esté desclorada). El objetivo es tener el mayor volumen de mosto posible cuya densidad sea de 1040 g/l (tenés el densímetro ahí, ¿no?). En la olla original van a quedar todos los restos de la malta, frenados por el filtro. Tiralos o usalos de abono.

Hervor

Ahora hay que hervir el mosto durante 1 hora. En cuanto rompa en hervor ponele la mitad del lúpulo. Y, 15 minutos antes, empezá a prepararte, porque viene la parte difícil de hacer cerveza. 
15 minutos antes de que termine de hervir activá la levadura poniéndola en un jarrito con un poco de agua desclorada tibia (con temperatura de entre 25 y 30 grados). Después de hacer eso, hay que esterilizar cosas. Usando el alcohol, esterilizá el fermentador, las mangueras y el enfriador. Todo lo que toque el mosto después de hervirlo tiene que estar esterilizado.
5 minutos antes de terminar el hervor, agregale lo que queda del lúpulo y el clarificante (nunca me acuerdo si acá va el whirlfloc o el isinglass :S).

Esto es lo más complicado

Apagá el fuego y hacé el whirlpool (o sea, hacé un remolino en la olla para que los restos que hay adentro queden en el medio). Enchufá el enfriador a las mangueras. Una va a a una canilla de agua fría y la otra al desagote. Meté el enfriador esterilizado adentro del mosto. Tapá la olla. Abrí la canilla para que el enfriador empiece a andar. Este es el momento más jodido cuando hacés cerveza. Si se contamina la cagaste.
Enfriá el mosto a temperatura ambiente y trasvasalo al fermentador. Cuando hayas terminado, tirale la levadura que activaste previamente y cerrá el fermentador, armando la trampa de aire (podés comprar una o improvisar una con una manguera y una botella de gaseosas). Dejá la cerveza en un lugar que tenga poca variación de temperatura. Si hacés Ale, tiene que estar alrededor de los 20 grados (aproximadamente).

Felicitaciones, en este paso ya tenés cerveza. Pero todavía falta para tomarla, la próxima te cuento como sigue.

Happy hacking,
Aureliano.

2012-05-26

Haciendo cerveza - Cosas que necesito

Reusables


  • 2 personas (una tiene que saber hacer cerveza, puedo ser yo ;) )
  • 2 ollas de 40 litros con una canilla en la parte de abajo. La forma de hacerlas es comprar 2 ollas de 40 litros de aluminio, hacerles un agujero con agujereadora y ponerles una canilla. Lo que yo hago es pedirlas prestadas (¡gracias Norbi!).
  • Tapadora (¡gracias Norbi!)
  • Fermentador (o su versión casera, un bidón de Sparkling con un tapón y una trampa de aire)
  • Mi cocina
  • Enfriador. En mi caso es un caño de bronce para gas doblado en forma de serpentina. Compré 3 metros y me quedé corto, mejor compren 5 metros. Si se sienten aventureros pueden hacerse un enfriador a contracorriente
  • 2 mangueras de pvc, las mangueras tienen que encajar en las canillas de las ollas y en la serpentina. Si cada manguera tiene 1,5 metros ya debería alcanzar. Un poco más es mejor
  • Termómetro, densímetro y probeta.
  • Botellas, calculá 20 litros. Podés comprarlas, cartonearlas o usar las botellas de cerveza que tenés tiradas en tu casa. Si comprás, comprate las de 660cm^3.

Consumibles

  • Maltas, lúpulos y levadura. Lo más fácil es comprar un kit en minicervecería como éste. Es mejor si comprás las maltas molidas.
  • Tapas para botellas (una por botella :p).
  • Azúcar de maíz (si querés ahorrar, podés usar azúcar blanca común y sale también).
  • Alcohol (es para esterilizar cosas, no va directo en la cerveza).

Protocolo

En general no vas a tener todas las cosas que hacen falta para hacer cerveza las primeras veces. Si tenés amigos que tienen los elementos, lo que se acostumbra es que te los presten y que después como pago les regales algo de la cerveza que hiciste. Si estás leyendo esto y me conocés, puedo prestarte algunas cosas; pero prometé que me las vas a cuidar.

En próximos posts voy a explicar cómo hacer la cerveza, suscribite al feed de rss o pasá por acá de vez en cuando para ver cómo sigue,
Aureliano.

2012-05-24

Pseudo-terminales en python

Hacer ptys en python es complicado. En este post (en inglés) muestran cómo hacer un programa en python pueda encapsular a otro y hacerle creer que tiene su terminal.

Happy hacking,
Aureliano.

2012-05-23

Recordatorio para mi mismo,
Si quiero que sudo me pida el password de nuevo tengo que correr sudo -k.

Happy hacking,
Aureliano.

2012-04-23

Cambiando el certificado de SSL de un ELB

Abajo pongo un script que hice en python para cambiar el certificado por un ELB usando boto. Asumo que el load balancer escucha en el puerto 443 (https). Cambien las constantes para que use las que les corresponda en su proyecto.

import boto

AWS_ACCESS_KEY = "AWS_ACCESS_KEY_HERE"
SECRET_KEY = "SECRET_KEY_HERE"

PRIVATE = """\
PRIVATE KEY .pem CONTENT HERE
"""
BODY = """\
CERTIFICATE .pem CONTENT HERE
"""
CHAIN = """\
CHAIN CERTIFICATE .pem content HERE
"""
CERT_NAME = "name-for-the-new-cert"
ELB_NAME = "elb-to-be-updated"

iam = boto.connect_iam(AWS_ACCESS_KEY, SECRET_KEY)
iam.upload_server_cert(CERT_NAME, BODY, PRIVATE, CHAIN)

cert = iam.get_server_certificate(CERT_NAME)

elb = boto.connect_elb(AWS_ACCESS_KEY, SECRET_KEY)
for lb in elb.get_all_load_balancers():
  if lb.name == ELB_NAME:
    lb.set_listener_SSL_certificate(443,cert.arn)


Happy hacking,
Aureliano.

2012-04-22

Bailé

Ayer bailamos con Ivana en "Flor de fiesta tanguera". Este es el video:

2012-04-19

Bailo


Bailo acá el sábado.

Los espero!

2012-04-08

Objetos en JS

Leyendo Hacker News me crucé una explicación re buena de cómo hacer objetos en JavaScript. Disfrútenla.

Happy hacking,
Aure.

2012-04-07

Problemas en mi red wifi

Estoy tratando de copiar archivos en mi red WIFI, pero estoy teniendo un problemita.
Tengo un modem ADSL WIFI como el que explico en mi post anterior. Puse en la red WIFI 2 compus a las que se le asignaron los IPs 10.0.0.3 y 10.0.0.4 respectivamente.
En ambas compus me conecté a la red WIFI y puedo navegar x internet. Cada una de ellas puede pinguear al gateway (10.0.0.2):

>ping 10.0.0.2

Haciendo ping a 10.0.0.2 con 32 bytes de datos:
Respuesta desde 10.0.0.2: bytes=32 tiempo=3ms TTL=64
Respuesta desde 10.0.0.2: bytes=32 tiempo=1ms TTL=64
Respuesta desde 10.0.0.2: bytes=32 tiempo=1ms TTL=64
Respuesta desde 10.0.0.2: bytes=32 tiempo=4ms TTL=64

Estadísticas de ping para 10.0.0.2:
Paquetes: enviados = 4, recibidos = 4, perdidos = 0
(0% perdidos),
Tiempos aproximados de ida y vuelta en milisegundos:
Mínimo = 1ms, Máximo = 4ms, Media = 2ms

y ambas pueden ser pingueadas desde el gateway.
BCM96338 ADSL Router
Login: admin
Password:
> ping 10.0.0.3
NoHang -> ping 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
56 bytes from 10.0.0.3: icmp_seq=0 ttl=128 time=5.0 ms
56 bytes from 10.0.0.3: icmp_seq=1 ttl=128 time=0.0 ms
56 bytes from 10.0.0.3: icmp_seq=2 ttl=128 time=0.0 ms

--- 10.0.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.0/1.6/5.0 ms
> ping 10.0.0.4
NoHang -> ping 10.0.0.4
PING 10.0.0.4 (10.0.0.4): 56 data bytes
56 bytes from 10.0.0.4: icmp_seq=0 ttl=128 time=0.0 ms
56 bytes from 10.0.0.4: icmp_seq=1 ttl=128 time=0.0 ms
56 bytes from 10.0.0.4: icmp_seq=2 ttl=128 time=0.0 ms
56 bytes from 10.0.0.4: icmp_seq=3 ttl=128 time=0.0 ms

--- 10.0.0.4 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
>
>

Pero no puedo hacer que se pingueen entre sí:
>ping 10.0.0.4

Haciendo ping a 10.0.0.4 con 32 bytes de datos:
Respuesta desde 10.0.0.3: Host de destino inaccesible.
Respuesta desde 10.0.0.3: Host de destino inaccesible.
Respuesta desde 10.0.0.3: Host de destino inaccesible.
Respuesta desde 10.0.0.3: Host de destino inaccesible.

Estadísticas de ping para 10.0.0.4:
Paquetes: enviados = 4, recibidos = 4, perdidos = 0
(0% perdidos),

Mirando las rutas, no veo nada que me diga un problema:
>route print -4 10.*
IPv4 Tabla de enrutamiento
===========================================================================
Rutas activas:
Destino de red Máscara de red Puerta de enlace Interfaz Métrica
10.0.0.0 255.255.255.0 En vínculo 10.0.0.3 281
10.0.0.3 255.255.255.255 En vínculo 10.0.0.3 281
10.0.0.255 255.255.255.255 En vínculo 10.0.0.3 281
===========================================================================
Rutas persistentes:
Ninguno

Se les ocurre cuál puede ser el problema?

2012-04-06

El modem wifi de ARNET

Hola,
si tienen wifi con arnet, quizás esta info les sirva. En mi casa, el ip 10.0.0.2 es el ip del access point. Si te conectás a http://10.0.0.2 podés cambiar algunas configuraciones básicas.
Pero hay más. Si te conectás por telnet a 10.0.0.2 contesta:

BCM96338 ADSL Router
Login:

Googleando un toque encontré acá que el usuario "admin" y password "alvlgeddl" les dan acceso a una bonita consola con comandos. Y si se sienten con ganas de usar un shell de Linux más normal tipean "sh" (sin las comillas) y van a la línea de comando.
Por último, también hay una interfaz administrativa escondida por http en http://10.0.0.2/admin.html que pueden usar.
Happy hacking,
Aure.

PD: En la consola, podés hacer "passwd usuario nuevo_password" y cambiar los passwords. Los posibles usuarios son: support, admin y user.
PD2: Obvio que los míos ya están cambiados ;).

2012-03-09

Jugando con el name mangling en python

No tiene sentido, pero a veces se puede cambiar el comportamiento de los objetos cambiando los nombres de las clases pero sin mencionar su nombre en el código, jugando con la forma cabeza de hacer name-mangling de los atributos privados:

$ python
Python 2.7.2+ (default, Oct 4 2011, 20:03:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A(object):
... def __init__(self): self.__sarlanga = 1
... def s(self): return self.__sarlanga
...
>>> B = A
>>> B

>>> class A(B):
... def __init__(self):
... B.__init__(self)
... self.__sarlanga = 2
...
>>> aa = A()
>>> aa.s()
2
>>> class C(B):
... def __init__(self):
... B.__init__(self)
... self.__sarlanga = 3
...
>>> c = C()
>>> c.s()
1

Happy hacking,
Aure.

2012-03-02

Derechos y deberes de padres y madres separados

Como muchos de ustedes saben, soy padre y estoy divorciado. Eso hizo que me preocupe por encontrar cuál es la forma éticamente correcta de manejar un montón de situaciones bastante complicadas, y estoy buscando un marco moral que me permita tomar decisiones correctas y justas.

Sé que "correcto" y "justo" son palabras complicadas, así que estoy tratando de tener una guía para mi mismo, que me permita evaluar si mis acciones, y las de mi ex, son justas y correctas.
Esto es lo que tengo hasta ahora:
  • Tanto la madre como el padre son igualmente responsables por el bienestar de sus hijos
  • Los gastos y esfuerzos necesarios para asegurar su bienestar deben ser equitativos.
  • Ninguno de los dos es responsable por el bienestar del otro.
  • Cada uno es responsable por la manutención de sí mismo, sin derecho a reclamar por gastos que son propios de cada uno a la otra parte.
  • La riqueza generada por ambos mientras fueron una pareja debe ser repartida equitativamente.
  • La riqueza generada por ambos antes de formar nuestra pareja o después de romperla es exclusivamente de cada uno de uno, y cada uno tiene potestad exclusiva sobre ella.
Espero comentarios. Me interesan especialmente aquellos de madres separadas (incluyendo divorciadas).

2012-02-09

Obteniendo las VMWare tools para usarlas con VMWare Player 4.0.2

Estoy usando VMWare Player 4.0.2 en un Linux Mint de 64 bits y quiero instalar las VMWare Tools en los guests que vaya haciendo. El problema es que VMWare Player no viene con los tools y la opción del menú para instalar las tools no anda :(.

Workarround:

  • Bajar el bundle de VMWare Workstation (en mi caso, se llama: VMware-Workstation-Full-8.0.2-591240.x86_64.bundle)
  • Extraerlo en un directorio. Para eso ejecuté: /usr/lib/vmware-installer/2.0/vmware-installer --install-bundle VMware-Workstation-Full-8.0.2-591240.x86_64.bundle --extract /tmp/vmware
  • Ejecutando find /tmp/vmware -name "*.iso" podés ver los ISOs de todos los sistemas operativos. Para instalarlos, montalos como CD en la VM correspondiente.

Happy hacking!

Fuente: http://brandonhutchinson.com/Installing_VMware_Tools_with_VMware_Player.html

2012-01-26

2012-01-14

¿En qué pensar cuándo bailamos tango?

Algo que es muy común cuando uno lleva a una principiante es que "baile sola". O sea, que da pasos que no son marcados. ¿Por qué? Creo que es el miedo al vacío, a que había que hacer algo en ese compás y el paso que le enseñaron era ése.
Poder esperar hasta el siguiente paso, manteniendo el equilibrio, no es fácil. Y a mi me gusta mucho hacer pausas cuando bailo y pasar 2 o 3 compases sin pisar (o sea, conservando el peso de los pies tanto míos como los de mi pareja). Entonces estuve buscando alguna forma de poder ayudar a que puedan estar sin pisar, cosa que hace que yo disfrute más del baile y que ellas bailen mejor (y, espero, que lo disfruten también). A lo que llegué, es que están demasiado enfocadas en los pasos. Creo que esto es algo común tanto para cuando llevamos como para cuando somos llevados.
Mi contrapropuesta es que pensemos en otra cosa. Pensemos en nuestra pareja de baile y como interactúa con nosotros. En el calor que se siente en las partes del cuerpo que están en contacto. Brazo con espalda, mano con mano, pecho con pecho, panza con panza, etc. Y hagamos eso todo el tiempo. Pensemos en cómo va variando cuando hacemos diferentes pasos, con la respiración. Si nos concentramos, a veces también podemos sentir los latidos del corazón.
Lamentablemente, cuando llevamos tenemos otras responsabilidades. Manejar el espacio y la circulación en la pista. Empezar y terminar las frases de la música. Preveer el final para no quedar pagando. Pero si tenés la suerte de estar siguiendo, podés entregarte 100% a sentir a tu pareja de baile, que es lo más lindo del tango.
Nos vemos en la milonga,
Aureliano.
PD: No, no doy clases de tango.

2011-12-12

El plagio es la forma más sincera de halago

Hoy salió la versión 4.0 de bindiff, y le incluyeron un feature que se llama "Combined visualization of two flowgraphs" que se parece mucho a lo que presenté en Hack.lu 2010 (y que presenté anteriormente en este blog). De todas maneras, me parece que les faltó ir hasta el fondo y unir cada par de basic-blocks en uno solo (si alguien de Zynamics ve este blog, miren mi paper para ver cómo hacerlo).

Happy hacking,
Aureliano.

2011-12-08

Un día bizarro

Ayer fue un día bizarro. A la mañana participé de la grabación de un programa del History Channel que se llama "Super Humanos" o algo así. En el mismo estuve con 2 amigos evaluando a Jaime García Serrano, que calculó raíces cuadradas, logaritmos, funciones trigonométricas, las inversas de las trigonométricas y factoriales, mientras nosotros teníamos que decir si lo calculaba bien o no, mirando los resultados en una compu.
Salí corriendo porque a la tarde tenía otro compromiso. A las 14.15 tenía turno para que me saquen una muela de juicio. Me sacaron la muela y ahora estoy tomando antibióticos y analgésicos, y el helado es mi principal alimento.
A la noche fui a La Glorieta, donde bailé algunos tangos y me encontré con amigos.
Al final, me fui a dormir.
PD: Me dijeron que el programa sale en abril.

2011-11-21

Zipeando working directories

Para zippear un directorio controlado por svn sin poner la info administrativa de svn podés ejecutar este comando en bash y va a andar:

find . -not \( -type d -name ".svn" -prune \) -type f -print | zip -@ ~/zip_file_name

Happy hacking,
Aureliano.

2011-11-17

La biblia y el calefón

EXPLICACIÓN DE UNA COMPARACIÓN EN LA LETRA CAMBALACHE

¡EXACTA REAL DEMOSTRABLE Y CREIBLE;PARECE MENTIRA QUE JAMAS LO EXPLICARAN LOS MILES DE ESCRIBAS, LITERATOS E INTELECTUALOIDES QUE DICEN " ESTUDIAR EL TANGO"

La Biblia y el Calefón –
Se habla de ello y la mayoría no sabe de qué se trata:
He aquí la historia de un hecho de la vida cotidiana, que acontecía en la ciudad de Buenos Aires –no sé si en otros lugares pasaba o no–, y que explica el porqué de la aparentemente surrealista asociación de la Biblia junto al calefón que aparece en el tango "Cambalache", cuyas letra y música fueron compuestas por Enrique Santos Discépolo en 1935.

La historia tiene relación con los baños, la higiene personal y la forma de realizarla; y como no se me escapa que algunos lectores pueden ser jóvenes y pueden no haber conocido otro tipo de baños que los que se estila usar en la actualidad al menos en el mundo occidental y cristiano, voy a recordar primero un par de datos que considero necesario sean tenidos en cuenta.

Los baños que conocemos y que en algunos lugares son llamados 'completos', es decir, los que constan como mínimo de retrete inodoro, lavabo y ducha (algunos exquisitos, como el irresponsable que escribe, exigen que además tenga bidet –artefacto desconocido en muchos sitios–) son relativamente nuevos.

Hasta finales del siglo XIX se utilizaban bacinillas (también llamadas ‘tazas de noche’), cuyos contenidos eran arrojados por las ventanas al grito de "agua va"; y antes aún, letrinas, que solían estar en los fondos de las casas.

En Buenos Aires coexistieron bacinillas y letrinas hasta principios del siglo XX, época en que las familias ‘acomodadas’ comenzaron a instalar baños.

Luego el uso de baños se generalizó y se empezó a construirlos en todas las viviendas, aun en las más modestas. El sencillo 'miniambiente' constaba al menos de retrete y lavabo y si los lujuriosos dueños de casa gustaban de practicar la morisca costumbre de lavarse todo el cuerpo más o menos seguido, y si además tenían medios económicos suficientes como para costearse ese capricho, los baños también tenían una ducha. Claro, si había una ducha era necesario calentar el agua, así que al lado de la ducha se instalaba un calefón.

Sin embargo, el papel higiénico tardó en obtener su carta de ciudadanía

para poder trabajar en limpio en estas sucias tierras y aun cuando apareció era bastante caro y no estaba al alcance de todas las familias, las cuales se veían obligadas a utilizar para esos fines sanitarios el vulgar papel de diario o, en su defecto, cualquier otro.

Por supuesto, eran muy estimados los papeles más sedosos, así que los sufridos usuarios trataban de conseguir en las verdulerías y fruterías los papeles con los que venían envueltas las manzanas y otros productos de campo.

Otro muy apreciado era el llamado ‘papel biblia’, especialmente delgado y suave.

Ahora bien, ya por entonces existía la Sociedad Bíblica, una de cuyas misiones parece ser la de difundir la Biblia protestante, para lo cual regalaba ejemplares del sagrado libro –en la actualidad, lo sigue haciendo–.

Pues, muchos de los habitantes de Buenos Aires deben de haber parecido devotos creyentes, ya que aceptaban de continuo esas gentilezas, y que siendo mayoría la grey católica, lo mismo pasaban y retiraban la biblia protestante tantas veces como sabían que la Sociedad las tenía en obsequio en las calles, plazas o en su sede central .
LA BIBLIA Y EL CALEFÓN

Sin embargo, cuentan los hombres dignos de fe (aunque Alá sabe más) que quienes obtenían esas Biblias les perforaban una tapa y las colgaban de un gancho de alambre, al lado del calefón, cerca del retrete, e iban arrancando las suaves hojas para usarlas como papel higiénico.

En este hecho se habría inspirado Enrique Santos Discépolo para decir con elegancia propia de un grande autor:

Igual que en la vidriera
irrespetuosa
de los cambalaches
se ha mezclao la vida,

Y HERIDA POR UN SABLE SIN REMACHE
VES LLORAR LA BIBLIA
JUNTO AL CALEFÓN.

Edgardo G. Maggiora
BARILOCHE

Gracias Mayca por este material!

Cómo, esto también es matemática?

Un post de este blog se va para arriba. Los números de Aure aparecen en el último libro de Paenza. Mirá la página 224.

Happy hacking,
Aureliano.

2011-11-07

Cortando video con ffmpeg

Para cortar video usando ffmpeg hay un comando que me resultó re-práctico. Lo pongo acá para acordarme.

ffmpeg -sameq -ss [start_seconds] -t [duration_seconds] -i [input_file] [outputfile]


Fuente: joeldare

2011-08-25

Por si alguna vez entran palomas en su server room.....

adapté una conocida canción para conmemorarlo. Pongo acá abajo letra y acordes.


Mim Sim Mim
Se equivocó la paloma, se equivocaba,
en vez de al norte, al server room
Do Sim MIm
pensó que el cable era paja, se equivocaba

Sol
Pensó que Sun era el cielo,
Mim
la mudanza era mañana,
Do Lam MIm
se equivocaba, se equivocaba
Lam Si7 Mim
que las bandejas manzanas,
Lam Si7 Mim Re
que la calor la nevada,
Sol Si7 Lam
se equivocaba, se equivocaba.

Si7 MIm
Que tu CAT,era tu blusa,
Do Si7 Do Re
que tu bandeja, su casa,
Mim Re Mim Mi7-Lam
se equivocaba, se equivocaba,
Re7 Sol Mim Lam
ella se durmio en la silla,
Si7 Mim
tu en la cumbre de un ra-ack.

Si7 MIm
Que tu CAT,era tu blusa,
Do Si7 Do Re
que tu bandeja, su casa,
Do Mim
se equivocaba, se equivocaba.

Enjoy!,
Aureliano


2011-08-04

Qué semana de mierda!

  • El domingo me levanté con 38 grados de fiebre. Como estaba enfermo no pude ver a mi hijo. A la noche tenía casi 39 de fiebre.
  • El lunes seguía con fiebre, así que falté al laburo. Como no me mejoraba, llamé al médico. El médico vino, me dijo que tenía una angina, me recetó un antibiótico y me dijo que tomara ibuprofeno para bajar la fiebre. Fui a la farmacia, compré todo, volví a casa, tomé el antibiótico y el ibuprofeno. Me bajó la temperatura y me fui a dormir.
  • Me desperté el martes a las 2 AM todo sudado y cagado de frío. Cuando vi que no podía dormirme del frío me levanté para sacarme la ropa toda mojada y me agarraron unos espasmos impresionantes. No podía dejar de temblar. Así que me cambié la remera y me volví a acostar. Seguía cagandome de frío.
  • Pasó como una hora y se me pasó el tembleque. Así que agarré el termómetro. Marcó 39.3. Me tomé otro ibuprofeno y me fui a dormir.
  • El martes me desperté sin fiebre, pero al mediodía ya estaba con fiebre de nuevo. A la noche me tomé otro ibuprofeno y el antibiótico. Como seguía hecho mierda, de nuveo no vi a mi hijo.
  • El miércoles me desperté un poco mejor, sin fiebre. Pero después del mediodía me agarró diarrea. Por suerte había tomado mucha agua y me la pude bancar. A la noche no tomé el ibuprofeno y me fui a dormir.
  • El jueves (hoy) me sentí un poco mejor, así que ¡fui a hacerme un tratamiento de conducto!. Ahora estoy bajo los efectos de los analgésicos recetados por la dentista.
Así que sumarizando mi semana queda así: angina, fiebre, diarrea y conducto.

Hasta la próxima,
Aureliano.

2011-06-17

Integración paver fabric

Update: Parece que se viene esto como parte de paver 1.1

Hice un pequeño hack y ahora puedo usar el API de fabric cuando escribo tasks de paver y que la tarea se ejecute una vez para cada host.

Para hacer eso, hice un decorator, que se llama multihost y es así:

from fabric import state, network

def multi_host(f):
"""\
Run the decorated function for each host in options.get("host_strings").

Will use the private key set in options.pk if set.
"""
def decoratee(options):
for host_string in options.get("host_strings"):
network.interpret_host_string(host_string)
pk = options.get("pk", None)
state.env.key_filename = [pk] if pk else None
f(options)

decoratee.func_name = f.func_name

return cmdopts((
("pk=", None, "Private key file"),
))(decoratee)

El uso es así:


from paver.easy import task, needs
from fabric import api

@task
def find_hosts(options):
options["host_strings"] = ["host1", "user@host2", "user2@host3:2222"]

@task
@needs("find_hosts")
@multi_host
def remote_hello_world(options):
api.run("echo hello world")


Happy hacking,
Aureliano.

2011-06-14

Tamaños de ventanas extraños en eclipse y workaround

En el laburo desde hace un tiempo estoy haciendo el experimento de correr varias VMs con los distintos proyectos en los que trabajo. Por lo tanto tengo varias VMs distintas (guests) corriendo que se conectan usando X a mi host.

En una de ellas tengo eclipse instalado con pydev. Y como host tengo un Windows 7 con X-Ming como server X. Y anda todo bastante bien salvo porque algunas ventanas de diálogo se van agrandando de formas extrañas hasta que se vuelve imposible usarlas. Y aparte, no sé por qué, no se pueden resizear usando el mouse (que sí se puede si lo corrés en Windows, gnome o kde normalmente).

Por lo tanto, busqué y encontré un workaround al problema, y edito a mano algunos archivos de configuración del workspace de eclipse para cambiar estos tamaños a una medida razonable para mi y para que quede documentado lo dejo anotado acá.

En el archivo ./org.eclipse.ui.ide/dialog_settings.xml sección DialogBoundsSettings setié:

<item value="1024" key="DIALOG_WIDTH"/>
<item value="768" key="DIALOG_HEIGHT"/>


En el archivo org.eclipse.ui.workbench.texteditor/dialog_settings.xml sección org.eclipse.ui.texteditor.FindReplaceDialog_dialogBounds setié:
<item value="1024" key="DIALOG_WIDTH"/>
<item value="768" key="DIALOG_HEIGHT"/>


En el archivo org.eclipse.search/dialog_settings.xml sección DialogBounds_SearchDialog setié:
<item value="1024" key="DIALOG_WIDTH"/>
<item value="768" key="DIALOG_HEIGHT"/>


Y por último, en el archivo org.tigris.subversion.subclipse.ui/dialog_settings.xml hice algo un toque distinto, seteando en la sección Workbench esto:
<item value="1280" key="CommitDialog.size.x"/>
<item value="768" key="CommitDialog.size.y"/>


Por supuesto, todos estos archivos hay que tocarlos con el eclipse apagado.

Happy hacking,
Aureliano.

2011-06-06

Sé lo que hiciste el verano pasado

Hola,

estuve ocupado últimamente así que no pude darle mucha pelota a mi blog. Hoy suspendo este silencio para contarles que estuve haciendo en el laburo los últimos meses. Lo que hicimos es un servicio para pentestear instancias y páginas web que estén hosteadas en AWS. Aunque mucho el nombre no me gusta (lo eligió la gente de marketing), se llama Core CloudInspect y está acá.

La idea es hacer pentests en 5 clicks y 20 dólares y, los primeros 3 son gratarola!.

Happy hacking,
Aureliano.

2010-10-28

Presentación en Hack.lu

Hace unas horas presenté en Hack.lu mi charla sobre aureliax. Aureliax es un software que sirve para mostrar diferencias entre diferentes versiones de una misma función, que es mostrada mediante un grafo de basic blocks. En cuanto pueda voy a poner on-line el white paper que explica cómo funciona y cuál es la base teórica que lo sustenta.
Por ahora estoy contento y cansado (acá en Luxemburgo son las 2 menos 20), y mañana tengo un largo día por delante.

Happy hacking,
Aureliano.

2010-09-21

Bajo el farol


Les recomiendo que vayan a ver esto. Yo fui la vez anterior, en abril, estuvo buenísimo y voy a ir de nuevo.

2010-09-04

Cómo trato de bailar a Pugliese

  • Escuchando el fraseo y siguiendo su intensidad.
  • Escuchando el compás, que aunque no siempre se note siempre está ahí.
  • Variando estilo y distancia del abrazo, pasando desde un tango milonguero, al tango salón y a veces hasta con abrazos típicos del tango nuevo. Todo dentro de un mismo tema.
  • Dando tiempo a la mujer para que también pueda hacer su propia interpretación y lucirse. Generalmente esos tiempos se dan en las partes más piano, que generalmente son a cargo del violín y/o en el final de la frase musical.
  • Es muy raro que haga paradas y el sanguchito, aunque si me parece que mi pareja lo quiere puedo llegar a marcar uno.
  • Giro en la parte ligada y camino usando contratiempos en la parte marcada.
  • En las pausas no hay cambios de peso, pero trato de mantener un dejo del movimiento que veníamos haciendo justo antes.
  • La elección del paso y la intensidad depende de la música, la pareja y la pista.
  • El final generalmente incluye una corrida de 5 o 7 pasos hasta el acorde dominante y quitar toda la tensión cuando suena la tónica suavemente en el piano.
Happy dancing,
Aureliano.

2010-07-30

Arte efímero


Marcador al agua sobre pizarrón blanco

2010-07-12

Una pequeña delicia del JavaScript

Qué valor debería dar el siguiente código:

"aDb".replace("D","$$")

Si pensaron "a$$b" se equivocaron. Da "a$b" (con un solo $).
Para que de el valor que esperaba ("a$$b") hay que hacer este hack:
"aDb".replace("D",function() { return "$$" })

¿Por qué?
Ni idea, pero anda así en rhino y V8, así que debe estar en la especificación.

Happy hacking,
Aureliano

2010-06-01

Flechas con RaphaelJS

Me encontré con que no hay ningún método para dibujar flechas en raphaelJS, así que me puse las pilas y programé uno:

 /**
* Returns a path in form of an arrow
* @param arrowSize is the size of the arrow end. Defaults to 10 pixels.
*/
Raphael.fn.arrow = function(x1, y1, x2, y2, arrowSize) {
var arrowSize = arrowSize || 10
var l = Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) )
var xStep = (x2 - x1) / l
var yStep = (y2 - y1) / l

// arrow point ends
var arrX1 = x2 + arrowSize * (yStep - xStep) / 2
var arrY1 = y2 + arrowSize * (-xStep - yStep) / 2
var arrX2 = x2 + arrowSize * (-yStep - xStep) / 2
var arrY2 = y2 + arrowSize * (xStep - yStep) / 2

var path = ["M", x1, y1, "L", x2, y2, //main line
"M", arrX1, arrY1, "L", x2, y2, "L", arrX2, arrY2] //arrow end

return this.path(path.join(" "))
}

Para usarlo hay que hacer:

var r = Raphael(....)
.....
var arrow = r.arrow(150,100,250,300)

2010-05-19

Cambiando el context-root

Esto es lo que tuve que hacer para que la webapp en java que estoy desarrollando con eclipse 3.5 y web tools platform ande en el context-path root:

  • Abrir el archivo .settings/org.eclipse.wst.common.component
  • Cambiar la entrada <property name="context-root" value="risky"> por <property name="context-root" value="/">
Happy hacking,
Aureliano

2010-04-27

Ahora tengo twitter

Saqué cuenta en twitter y voy a empezar a twittear (¿se escribe así?). Si quieren seguirme mi usuario es aurelianito.

En cuanto tenga alguna idea de lo que opino de twitter la mando por acá.

Happy hacking,
Aureliano

2010-04-06

Bajo el farol

Update: si quieren pueden escuchar algunas canciones del show en su página de myspace

Este sábado 10 de abril a las 23:30 hs mi amiga y gran cantante Natalia Iñón presenta su espectáculo "Bajo el farol" en la Casona del Teatro, que queda en Corrientes 1975 (Ciudad de Buenos Aires). El repertorio está compuesto por canciones de Edith Piaf, Marlene Dietrich y algunos tangos. Les sugiero que vayan a escucharla ya que es una cantante exquisita.

Nos vemos allá,
Aureliano

2010-03-08

Pequeñas cosas que me molestan

Un compañero de laburo dice que las personas que nos dedicamos a la programación y aledaños generalmente tenemos alguna tendencia al desorden obsesivo-compulsivo. Yo hice mi mea-culpa y acá escribo una lista de pequeñas cosas que creo que me molestan por tener algo de esa tendencia:
  • Salir a comer y que algunos pidan postre y otros no.
  • Salir a comer y que algunos pidan entrada y otros no.
  • Jugar fútbol en cantidades impares (ej: 5 contra 4)
  • Que los platos colocados en el escurridor no estén cada uno en una rendija y ocupando rendijas consecutivas desde el extremo más lejano del mismo.
¿Qué cosas equivalentes les molestan a ustedes?,
Aureliano

2010-03-03

Configurando lyx para escribir proceedings de ACM

Hoy configuré el lyx para que use la clase de LaTeX que piden para los proceedings de ACM y fue bastante más molesto de lo que esperaba. Esto lo hice en un ubuntu 9.10 casi pelado (con lyx y no mucho más). Acá les cuento los pasos:

  1. Copiá acm_proc_article-sp.cls a $HOME/texmf/tex/latex
  2. Corré "texhash ." en $HOME/texmf/tex/latex
  3. Poné en ./lyx/layouts el archivo acm_proc_article-sp.layout
  4. Arrancá lyx, andá a Tools->Reconfigure y volvé a arrancar lyx.
  5. Ahora en Document->Settings->Document Class está disponible la clase de los proceedings de ACM bajo el nombre "ACM Sig Proceedings".
Happy hacking,
Aureliano.

2010-02-22

Una reflexión sobre facebook

El otro día estaba cenando con unos amigos y estabamos hablando de como me echaron de FB. Y un amigo hizo una analogía re-buena.
¿Qué pasa si te ponés a bailar en los pasillos de un shopping? Lo más probable es que venga alguien de seguridad y te pida "amablemente" que te retires del lugar. En cambio si te ponés a bailar en el medio de una plaza, más allá de algunas miradas raras no debería pasarte nada.
¿Y por qué? El asunto es que nos olvidamos que el shopping no es un espacio público sino un espacio privado al que te dejan entrar cuando quieren, como quieren y en el que pueden aplicar toda clase de reglas arbitrarias. En cambio, una plaza es un lugar mucho más público.
Y con facebook pasa lo mismo. Es un espacio que nos olvidamos que es privado, pero lo es. Entonces nos molesta que nos apliquen reglas raras.
Ojalá estas cosas que me pasaron a mi (y a otros) sirvan para que entendamos la diferencia.

Happy hacking,
Aureliano.

2010-02-09

Exportando gráficos en dia a pdflatex

  1. Hacé tu gráfico en dia
  2. Exportarlo como "LaTeX PGF macros"
  3. En el principio de tu .tex poné:
  4. \usepackage{tikz}
  5. En el lugar donde quieras poner tu caption poné
    \begin{figure}
    \centering
    \input{archivo_exportado_de_dia.tex}
    \caption{Acá va el caption}
    \label{aca_va_la_label}
    \end{figure}
  6. Compilá el .tex principal con pdflatex
  7. Miralo con tu visor de pdfs favorito
Happy hacking,
Aureliano.

2010-02-07

Como ven los fanas de un lenguaje a los otros

Mirar lambda the ultimate es siempre interesante. Y esta vez me crucé con una perlita que quiero compartir con ustedes:

2010-02-05

Segundo advisory

Ayer salió mi segundo advisory. Lo que encontramos con Manuk es que parte administrativa de la aplicación LanDesk Manager tiene un cross-site request forgery que hace que si enganchás a un administrador se pueda hacer un cross-site scripting no persistente y, aún más divertido, hacer un OS command injection.
Aún más divertido, es que se puede usar modprobe y cargar módulos de kernel de linux que uplodee usando el command injection.
Más detalles en la página de Core.
Happy hacking,
Aureliano

2010-01-27

Simplificando

Ayer me di cuenta que no necesito rehacer los classloaders de java para cargar scripts de JavaScript, ya que puedo usarlos y son todo lo flexibles que necesito (y más). Inclusive, si por una de esas casualidades llegara a hace falta, creo que puedo hacer uno en rhino y todo. Por lo tanto decidí que mi lógica para cargar módulos tenía una indirección de más (la lista de loaders) y lo cambié para que use el classloader y listo. Fíjense en la nueva implementación de loadMod y como se simplificó el uso de los loaders.
En la versión del código que estoy usando ahora, también hice que los módulos se carguen un toque distintos para que haya mejores stack-traces (ese cambio está en la función require). Bueno, abajo pongo el código:


/*
* Does not support relative paths (yet?).
* Can be invoked by several threads.
*
* Uses the classloader to fetch js modules.
*/
var require = function (id) {

try {

require.lock.lock() // Avoid threading issues while loading modules.

if (!require.modules[id]) {

var modCode = require.loadMod(id)

var exports = {}
require.modules[id] = exports
var module = {
id : id
}

var context = {
exports: exports,
module: module,
}

if(!modCode) {
throw new require.RequireError(id, "module not found")
}

org.mozilla.javascript.Context.getCurrentContext().evaluateString(
context,
modCode,
id,
1,
null
)
/*
Old style invocation, should work in the browser but has worst error messages.

var f = new Function("require", "exports", "module", modCode)
f.call(context, require, exports, module) */
}

return require.modules[id]
} catch (x) {
if (x instanceof require.RequireError) {
throw x
} else {
throw new require.RequireError(id, x)
}
} finally {
require.lock.unlock()
}
}

require.loaders = []
require.modules = {}
require.lock = new java.util.concurrent.locks.ReentrantLock()

var RequireErrorProto = {}

require.RequireError = function(moduleId, cause) {
this.moduleId = moduleId
this.cause = cause

}
require.RequireError.prototype = RequireErrorProto
require.RequireError.prototype.toString = function() {
return "Error loading " + this.moduleId + ( this.cause ? ". Cause: " + this.cause : "" )
}
require.RequireError.prototype.name = "RequireError"

require.load = function(path) {
return java.lang.Class.forName("java.lang.String").getResourceAsStream(path)
}

require.loadMod = function(id) {
function path(id) {
return "/" + id + ".js"
}

function readFromStream(stream) {
var io = java.io
var reader = new io.BufferedReader( new io.InputStreamReader(stream) )
try {
var stringBuffer = new java.lang.StringBuffer()

var line = ""
while( line = reader.readLine()) {
stringBuffer.append(line)
stringBuffer.append("\n")
}

return stringBuffer.toString()
} finally {
reader.close()
}
}

var stream = require.load(path(id))
if (!stream) { return null }

return readFromStream(stream)
}

/**
* Resets the module cache.
*
* It will reload all the modules. Old modules referenced will still be working.
*/
require.reset = function() {
try {
require.lock.lock()
require.modules = {}
} finally {
require.lock.unlock()
}

}

Este cambio también simplifico el RhinoServlet, y ahora toma sus scripts del classpath también.

Happy hacking,
Aureliano

2010-01-25

Parseando CSVs con una expresión de JavaScript

Para parsear un CSV con datos numéricos hay que hacer esto:


text.split("\n").map( function(r){
return r.split(",").map( function(d) {
return parseFloat(d)
} )
} )

Esto solo anda si tu intérprete de JavaScript tiene Array.prototype.map definido. Sino antes de eso tenés que definirlo así:

Array.prototype.map = Array.prototype.map || function( f ) {
var r = []
for (var i=0; i<this.length; i++) {
r[i] = f(this[i])
}
return r
}

2010-01-18

2010-01-17

Generando xhtml con e4x

Primero hay que setear el namespace por default:

default xml namespace = "http://www.w3.org/1999/xhtml"


Para generar elementos, uso esta función:
function elem(name) { return <{name} /> }


Para setear un attributo cualquiera esta función:
function attr(elem, key, value) { elem["@"+key] = value }


Y puedo usar elem.appendChild para agregar como hijo de un elemento otro o un texto como string que es escapado.

Happy hacking,
Aureliano.

2010-01-12

Entrada de BibTeX en Google Scholar

Si estás logueado en Google, podés setear Google Scholar para que te muestre las entradas de bibtex.
Para eso tenés que ir a Scholar Preferences -> Bibliography Manager y elegir Show links to import citations into BibTeX.

Happy hacking,
Aureliano

(Sacado de acá)

2010-01-10

Implementación de require en Rhino

Hoy estuve hackeando un toque y modifiqué el RhinoServlet que les mostré en este post para poder tener módulos en Javascript. El API que hice es un subset de lo definido en CommonJS. En particular, soporta require pero no los paths relativos de módulos (o sea, los que empiezan con . o ..). También le puse a todo un lock para que pueda usarse en un entorno concurrente, pero si un módulo tarda mucho en cargarse puede llegar a ser un problema.
Lo que me parece más interesante de mi prototipo es que se pueden agregar fácilmente nuevos loaders de módulos de JavasScript. Ya vienen por defecto loaders para cargar desde el classpath y desde la webapp, pero si quieren poder poner sus módulos en /WEB-INF/example, alcanza con agregar una línea en init.js:

require.loaders.push( require.stdLoader(servlet.servletContext, "/WEB-INF/example/"))

Bueno, basta de cháchara, acá está la versión modificada del RhinoServlet:
package aure.jslib;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

public class RhinoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Scriptable initialScope = null;

public void runJs(Context cx, String scriptLocation, Scriptable scope) throws IOException {

InputStream is = this.getClass().getResourceAsStream(scriptLocation);
if( is == null) {
is = this.getServletContext().getResourceAsStream("/WEB-INF/js/" + scriptLocation);
}
Reader jsReader = new InputStreamReader(is);

cx.evaluateReader(scope, jsReader, scriptLocation, 1, null);
}

public static void addJavaObjectToScope(Scriptable scope, String name, Object obj) {
ScriptableObject.putProperty(scope, name, Context.javaToJS(obj, scope) );
}

@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
addJavaObjectToScope(scope, "servlet", this);
addJavaObjectToScope(scope, "config", config);

this.runJs(cx, "initRequire.js", scope);
this.runJs(cx, "init.js", scope);

this.initialScope = scope;
} catch (IOException e) {
throw new ServletException(e);
} finally {
Context.exit();
}
}

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
scope.setParentScope(this.initialScope);

addJavaObjectToScope(scope, "request", request);
addJavaObjectToScope(scope, "response", response);

this.runJs(cx, "start.js", scope);
} finally {
Context.exit();
}
}
}

Noten que toqué el init para que agregue el require y cambié la forma de levantar javascript. Por otro lado este es el javascript en initRequire.js, que tiene la implementación del require:

/* Based on http://www.davidflanagan.com/demos/require.js
* but heavily modified.
*
* Does not support relative paths (yet?).
* Can be invoked by several threads.
*
* Uses the servletContext and the classloader to fetch js modules.
*/
var logger = java.util.logging.Logger.getLogger("sarasa")

var require = function (id) {

try {

require.lock.lock() // Avoid threading issues while loading modules.

if (!require.modules[id]) {

var modText = require.loadMod(id)

var context = {}
var exports = {}
require.modules[id] = exports
var module = {
id : id
}

var f = new Function("require", "exports", "module", modText)
f.call(context, require, exports, module)
}

return require.modules[id]
} catch (x) {
throw new Error("Can't load module: " + id + ": " + x)
} finally {
require.lock.unlock()
}
}

require.loaders = []
require.modules = {}
require.lock = new java.util.concurrent.locks.ReentrantLock()
require.loadMod = function(id) {
var modText = null
var i = 0
while (modText == null && i < require.loaders.length) {
modText = require.loaders[i](id)
i++
}
return modText
}

// Setup loaders for files in the classpath, files in WEB-INF and files in the
// web-app (usually served to the client)
require.stdLoader = function(source, prepend) {
// Support functions
function readFromStream(stream) {
var io = java.io
var reader = new io.BufferedReader( new io.InputStreamReader(stream) )
var stringBuffer = new java.lang.StringBuffer()

var line = ""
while( line = reader.readLine()) {
stringBuffer.append(line)
stringBuffer.append("\n")
}

return stringBuffer.toString()
}

function path(id) {
return prepend + id + ".js"
}

var f = function(id) {
var stream = source.getResourceAsStream(path(id))
return stream ? readFromStream(stream) : null
}

return f

}

require.initStdLoaders = function() {
// classpath loader
require.loaders.push( this.stdLoader(servlet["class"], "/") )

// web-app context loader
require.loaders.push( this.stdLoader(servlet.servletContext, "/") )
}

require.initStdLoaders()

Empecé a hacer esto mirando el código en http://www.davidflanagan.com/demos/require.js pero al final quedó bastante distinto, sobre todo porque tiene la opción de tener muchos loaders.
Las cosas que me quedan para hacer son hacer que acepte paths relativos (que para que sea thread-safe hace falta que haga algunos truquitos) y hacer que en vez de usar
   var f = new Function("require", "exports", "module", modText)
f.call(context, require, exports, module)

para invocar el módulo haga algo usando el API de rhino para poder tener errores donde aparezca el nombre del módulo y el número de línea si hubo algún problema.

Escucho comentarios y sugerencias.

Happy hacking,
Aureliano.

Eclipse plug-in para app-engine

¿Por qué te negás a usar dependencias de otros proyectos de eclipse?
¿Por qué no recompilás bien cuando está corriendo el web-server en modo debug y uso resources de adentro del classpath?

Bueno, por ahora son 2 problemas que creo poder "workarroundear".

Happy hacking,
Aureliano.

2010-01-08

2 placas y default gateway

Hoy estuve configurando una VM con ubuntu que tiene una placa en modo bridged por DHCP y otra host-only estática. El problema que tuve fue que no encontraba la forma que la ruta por default sea la ruta por default que informa el dhcp. La solución que encontré fue hacer que la métrica de la ruta por default de la ip estática sea más grande.

Este es el archivo /etc/network/interfaces que terminé usando:

auto lo eth1 eth0
iface lo inet loopback

iface eth0 inet dhcp

iface eth1 inet static
address 172.17.17.16
netmask 255.255.255.0
network 172.17.17.0
broadcast 172.17.17.255
gateway 172.17.17.1
metric 200

Y la posta está en la última línea.

Probé sacar la entrada de gateway y agregar una entrada borrando la ruta que me sobraba (up route del default gw 172.17.17.1) y no funcionó.

Se les ocurre alguna otra forma de arreglar esto?

Happy hacking,
Aureliano.

2010-01-05

2 servlets para correr javascript

Estuve con algo de tiempo y me puse a probar como hacer para ejecutar JavaScript en el server. E hice 2 implementaciones (o sea, 2 servlets programados en Java). La primera que hice usa javax.script (que viene por defecto en Java 6) y me parece que el API es más cómoda pero tiene 2 limitaciones que no me gustaron, no se puede heredar de clases Java en JavaScript y no encontré cómo hacer para bindear un método de Java a JavaScript. Este es el código:

package aure;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JsServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

private ScriptEngine jsEng = new ScriptEngineManager()
.getEngineByName("js");
private Bindings initBindings = this.jsEng
.getBindings(ScriptContext.ENGINE_SCOPE);

public JsServlet() {
super();
}

@Override
public void init(ServletConfig config) throws ServletException {
try {
super.init(config);

this.initBindings.put("config", config);
this.initBindings.put("servlet", this);

this.runJs("init.js", this.initBindings);
} catch (ScriptException e) {
throw new ServletException("Error running init.js", e);
}
}

public void runJs(String scriptLocation, Bindings bindings)
throws ScriptException {
Reader jsReader = new InputStreamReader(this.getServletContext()
.getResourceAsStream(scriptLocation));

this.jsEng.eval(jsReader, bindings);
}

protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {

try {
Bindings bindings = jsEng.createBindings();
bindings.putAll(this.initBindings);
bindings.put("request", request);
bindings.put("response", response);

this.runJs("start.js", bindings);
} catch (ScriptException e) {
throw new ServletException("Error running javascript", e);
}
}

}

La segunda usa rhino bajado desde mozilla y por lo tanto no tiene esas limitaciones, pero el API para embeber JavaScript en Java es más fea. Acá está el código de la segunda versión:
package aure;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

public class RhinoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Scriptable initialScope = null;

public void runJs(Context cx, String scriptLocation, Scriptable scope) throws IOException {
Reader jsReader = new InputStreamReader(this.getServletContext()
.getResourceAsStream("/WEB-INF/js" + scriptLocation));

cx.evaluateReader(scope, jsReader, scriptLocation, 1, null);
}

public static void addJavaObjectToScope(Scriptable scope, String name, Object obj) {
ScriptableObject.putProperty(scope, name, Context.javaToJS(obj, scope) );
}

@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
addJavaObjectToScope(scope, "servlet", this);
addJavaObjectToScope(scope, "config", config);

this.runJs(cx, "/init.js", scope);

this.initialScope = scope;
} catch (IOException e) {
throw new ServletException(e);
} finally {
Context.exit();
}
}

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
scope.setParentScope(this.initialScope);

addJavaObjectToScope(scope, "request", request);
addJavaObjectToScope(scope, "response", response);

this.runJs(cx, "/start.js", scope);
} finally {
Context.exit();
}
}
}

Ambas versiones ejecutan WEB-INF/js/init.js cuando se carga el servlet (tiene bindeados el servlet y la configuración del servlet) y WEB-INF/js/start.js cuando se atiende un pedido (agrega a los bindings lo que se haya puesto en init.js, el servlet, la configuración, el request y el response.

La idea de todo esto es ponerme las pilas e implementar las cosas que dije en este post hace casi 3 años, ya que ahora parece que se está poniendo de moda usar JavaScript.

Espero que les parezca interesante, me voy a dormir.

Happy hacking,
Aureliano.

2009-12-07

Cómo me echaron de facebook


Esta es la lista de eventos que pasaron hasta que me echaron de Facebook:
  1. 2007-11-10: Primera invitación a facebook recibida por mail
  2. 2009-09-27: Me suscribo a facebook
  3. 2009-09-30: Creo el grupo "Destruyendo facebook desde adentro"
  4. 2009-10-04: Publicito el grupo en un post de mi blog.
  5. 2009-10-17: Me linkea vivalinux. Entran más de 500 personas al blog en 2 días. El post del punto anterior es trolleado.
  6. 2009-10-18: Sin ningún tipo de aviso bloquean mi cuenta en facebook.
  7. 2009-10-19: Empieza la seguidilla de mails de/a facebook. El primero es este: "I've checked out on the links of the http://www.facebook.com/help.php?page=45 page and I didn't violate any rules.

    Can you inform me why the account was disabled?

    Thanks in advance,
    Aureliano Calvo."
  8. 2009-10-22: Contesta facebook (enfasis mío):"Hi Aureliano,

    Fake accounts are a violation of our Statement of Rights and Responsibilities. Facebook requires users to provide their real first and last names. Impersonating anyone or anything is prohibited. Unfortunately, we will not be able to reactivate this account for any reason. This decision is final.

    Thanks for your understanding,

    Johanna
    User Operations
    Facebook"
  9. 2009-10-22: Contesto yo (enfasis mío):"Hi,
    I've been falsely accused of impersonating someone else and this is just not true. I'm Aureliano Calvo, this is my e-mail and you can google for me. I can also provide several proofs of my identity and I'm willing to send photographs of my driver license, my passport or my identity card.

    Can you reactivate the account?

    Aureliano.
    "
  10. 2009-10-23: Vuelve facebook :"Hi Aureliano,

    Unfortunately, your account has been permanently disabled for violating Facebook's Statement of Rights and Responsibilities. We will not be able to reactivate it for any reason, nor will we provide further explanation of your violation or the systems we have in place. This decision is absolutely final.

    Thanks,

    Johanna
    User Operations
    Facebook"
  11. 2009-11-21: Pido por mail que borren todos mis datos de facebook:"I would like to have removed all my data from the facebook servers (generated from the account asociated with this e-mail).

    Thank you very much in advance,
    Aureliano Calvo"
  12. 2009-11-25: Contesta facebook sobre la remoción de datos:"Hi Aureliano,

    Facebook users have the option to either deactivate or delete their accounts. The differences between the two options are described below.

    If you deactivate your account, your profile and all information associated with it are immediately made inaccessible to other Facebook users. What this means is that you effectively disappear from the Facebook service. However, we do save your profile information (friends, photos, interests, etc.), so if you want to reactivate at some point, your account will look just the way it did when you deactivated. Many users deactivate their accounts for temporary reasons and expect their information to be there when they return to the service. You can deactivate your account through the "Deactivate Account" link on the Account page.

    If you do not think you will use Facebook again and you would like to delete your account, you can do this yourself by navigating to the following page:

    http://www.facebook.com/help/contact.php?show_form=delete_account

    Please keep in mind that once your account is deleted, you will not be able to reactivate the account or retrieve any of the content or information you have added.

    If you are currently unable to access your account, you will need to reset your password in order to log in. In order to do so, click the "Forgot your password?" link that appears above the field where you would normally enter your password. Entering your login email address on the next page will cause a new password to be sent to that email address. Once you receive your new password and can log in, you can deactivate or delete your account using the steps outlined above. We apologize for any inconvenience this may cause.

    Thanks for contacting Facebook,

    Brett
    User Operations
    Facebook"
  13. 2009-11-25: Contesto que no puedo porque deshabilitaron la cuenta:"I've requested that all my data should be removed from the facebook servers by email because my account has been disabled.
    Please remove all my data from the facebook system.

    Thank you very much,
    Aureliano Calvo."
  14. 2009-11-29: Me dicen que me joda que se quedan con todos los datos:"Hi Aureliano,

    When an account is disabled, the profile and all information associated with it are immediately made inaccessible to other Facebook users. What this means is that you effectively disappear from the Facebook service. In addition, Facebook does not use information associated with disabled accounts.

    Unfortunately, for safety and security reasons, we cannot delete from our servers information associated with disabled accounts. We also cannot grant you access to a disabled account to retrieve content from it, nor can we provide you with any content that was associated with this account. We apologize for any inconvenience this may cause. This decision is final.

    Thanks for your understanding,

    Brett
    User Operations
    Facebook"
Conclusiones:
  • Facebook contesta en tiempo y forma los pedidos por mail.
  • Facebook no identifica a las personas que contestan y no toma responsabilidades.
  • Facebook echa gente que no viola sus términos y condiciones (el punto que dicen que violé es mentira)
  • Facebook se niega a dar información sobre que hiciste mal (probablemente para cubrirse del punto uno) y encima lo hacen mal (como se ve en el punto anterior).
  • Facebook se niega a borrar los datos de la gente que echa (cosa que, hasta donde yo sé, es ilegal en Argentina).
O sea, mejor irse lo antes posible de ahí. No dejes que los mercaderes de relaciones te dominen.

Happy hacking,
Aureliano.