Automatic login to SSH with Putty

Go to the PuTTY homepage and download PuTTY, PuTTYgen and Pageant. Put them in an easily accessible directory like %PROGRAMFILES%\Putty.

Launch puttygen.exe and click on Generate, then move your mouse in the space below the progress bar to create some entropy for the key randomness. Once the key is generated lets complete the available fields:

  • Key comment is just a comment so anything will do, putting username-putty seems quite logical.
  • Key passphrase is actually a password to unlock the key. Put something complex in here but make sure you’ll remember it in the future!!!
  • Confirm passphrase, here you just input again the password to confirm you know which is it.

Now click on Save private key to store it permanently on your hard disk. Choose a secure place for it, I can’t strength enough how important is that this key remains secret. A good location could be %USERPROFILE%\ssh\putty.ppk.

Do not close PuTTYgen just yet, we need to copy the public key to our server (or servers). Connect to the remote server with your username and password as normal, go to your home directory and create a directory named .ssh if it doesn’t exists already. Create a text file named authorized_keys2 in the .ssh/ directory, inside that file copy the public key from PuTTYgen in a single line, save the file and exit the shell. Make sure the .ssh directory and its contents are only accessible by you (chmod -R og= .ssh). Repeat this step for each server you want to access with your public key.

The next step is to configure PAgeant (PuTTY Authentication Agent) to automatically start with Windows. Just create a shortcut in your Startup folder, the target should be something similar to %PROGRAMFILES%\Putty\pageant.exe "%USERPROFILE%\ssh\putty.ppk", change it to suit the paths you’ve used.

Double click it to avoid having to restart to launch it, a small pop-up window should show asking for your passphrase, type it and press Ok. If you have typed the correct passphrase a small blueish icon should show on you system tray, right click it to start a new session or launch a pre-configured one. If everything is allright PAgeant should take care of authenticate you.

Just a simple tip in case you don’t know, you can specify an username together with the server address by using this syntax: username@server.com. This way the authentication is completely automatic.

There are also another couple of great companion tools from PuTTY: PSCP and PSFTP. The first is a command line tool to transfer files securely between computers, the second is a text mode FTP client using a secure SSH connection. Specially the PSCP can be handy to be used in batch files to automatize some tasks.

PLEASE READ: Be careful with using public keys authentication to connect to a server. The steps I described are ok if you have the access to your computer restricted, do not leave PAgeant running while you’re away from your computer!

Los sitios web deberían ser fáciles de crear

Este es un post filosófico que llevo algún tiempo preparando para aclarar mis ideas. Como dice el título, los sitios web (aplicaciones web incluidas) deberían ser fáciles de crear. El sitio web típico tiene unas pocas docenas de páginas, un par de formularios y sindicación RSS como mucho. No parece que sea algo muy complejo, menos aun si tenemos en cuenta que la infraestructura para que funcionen es asequible, contrastada y potente. Algunos (yo me incluía en ese grupo hasta hace unos meses) culpan el hecho de la complejidad de crear un buen sitio web a lo enrevesado del entorno, un entorno no controlado como es un navegador web, donde las sutiles diferencias entre versiones y marcas suponen elevar exponencialmente la complejidad de la creación. La realidad en mi opinión es distinta.

El paradigma de programación más utilizado actualmente para el desarrollo de sitios web es el popular MVC (Model-View-Controller), algo que ya tiene unos cuantos años pero que solo en los últimos dos o tres se ha empezado a utilizar para el desarrollo de webs simples. La idea de ese concepto es que dividimos el desarrollo en tres capas diferenciadas. El Modelo se encarga de hacer el acceso a los datos uniforme, la lógica de negocio queda encapsulada en esta capa. La Vista se encarga de la presentación de la información, formateando los datos obtenidos del Modelo de una manera atractiva para el visitante. Por último el Controlador es quien controla quien puede ver que y bajo que circunstancias, además de ser el pegamento que une todas las piezas. Pues bien, resulta que para un sitio web normalito no necesitamos tantas capas, porque la realidad es que esas capas ya existen en la infraestructura utilizada, como por ejemplo con un stack LAMP.

Apache no es más que un Controlador, MySQL es un Modelo y los ficheros HTML son la Vista. Estamos de acuerdo en que esa infraestructura es muy genérica y que trabajar con ella es como construir una casa con herramientas manuales. Pero por que ocultar totalmente esas herramientas para substituirlas por otras nuevas más lentas y menos flexibles? Hablemos de REST, la filosofía detrás de la World Wide Web.

REST es el diseño en el que se modeló la web, se basa en que hay un conjunto de recursos identificados globalmente (la conocida URL) que pueden obtenerse en diferentes formatos (HTML, XML, PDF…). El diseño es realmente elegante y lo mejor de todo es que es algo probado y contrastado durante casi dos décadas. Mi conclusión es que si hacemos un sitio web este ha de hacerse en base a los principios básicos del medio donde reside, de lo contrario sería como intentar hacer un barco para ir por una carretera, seguro que podemos añadir ruedas pero seguirá pareciendo un barco en vez de un coche.

Así que juntando lo comentado arriba sobre LAMP como framework con el diseño REST, podemos obtener un sistema muy potente, flexible y fácil de utilizar. Para empezar tenemos que aprovechar la infraestructura disponible, y aprovecharla con criterio, como por ejemplo no almacenar las páginas HTML en una base de datos sino en el disco. A primera vista vemos que solo con el servidor web, la base de datos y el HTML estamos como hace 10 años, editando los ficheros con un editor y subiéndolos por FTP para publicarlos. Necesitamos algo que complete esas herramientas y ese algo son los lenguajes interpretados, ya sea PHP, Perl, Python, Java o Ruby. Estos lenguajes nos permitirán crear el pegamento necesario para ofrecer soluciones modernas de una manera simple y escalable. La idea es volver unos 5 años hacia atrás y retomar la costumbre de hacer una web con ladrillos, utilizando scripts prácticamente independientes para crearla. Después de todo PHPNuke fue popular pero no era la solución, aunque detrás de él hayan aparecido miles de sucesores intentando solucionar sus problemas, que lo único que han conseguido es ocultar esos problemas con capas y capas de complejidad añadida.

En un próximo artículo comentaré sobre una posible implementación de todo esto. La idea básica es la de quitar capas de complejidad de nuestros scripts para poder concentrarnos en la funcionalidad y el contenido, eliminando posibles puntos negros de errores y aprovechando la escalabilidad inherente a la web.

Rectangle Packing (2D packing)

I’m working on a little thing which I don’t want to speak about just now, lets see if I can get it to do what I want first before making it public. However for that project I needed to pack several small rectangles of varying dimensions into a bigger one without them overlapping.

At first it seem like an easy task but the more I thought about it the more difficult it was. After a bit of research I found out that until today this seems to be a non resolved problem, there are algorithms which offer a pretty decent approximation to the optimal result though. The problem is commonly known as the Bin Packing problem and in this case I needed to work with two dimensional objects (rectangles) so it gets a lot more complicated.

After more googling I found an article by Jim Scott with pseudo code to solve a similar problem, the article explains on how to pack several lightmaps into a single texture. It was the easiest to understand algorithm I had found so I went ahead and implemented it in PHP. I had it in a few minutes but I wanted to fine tune the results by feeding it the rectangles by different sorting criteria, since it seems to be a good way to achieve the best results. Well, I got tired to slowly generating the image in PHP to check the results with every minor variation so I implemented a JavaScript version which allows to see the result in real time.

This algorithm can be used for a wide variety of problems, from packaging small sprites in a big image to allocate tasks in complex projects (use the width for the team developers and the height for the time).

A simple usage example could be as follows:

var coords,
    packer = new NETXUS.RectanglePacker( 512, 512 );

for (var i=0; i<images.length; i++) {
    coords = packer.findCoords( images[i].width, images[i].height );
    alert( 'Image of ' + images[i].width + 'x' + images[i].height +
         ' allocated at ' + coords.x + 'x' + coords.y
    );
}

I’ve put up a demo so you can try it and see the results with different parameters. Tip: the best results seems to be with the blocks sorted by the magic method and reversed.

You can download the source code from this link.

Hex2Dec and Dec2Hex

For secret reasons I need to usually convert hex strings to decimal notation. This can be easily done with a scientific calculator, like the one supplied with Windows, but it’s slow and I’m usually in a hurry to convert them :)

So I took a look at GreaseMonkey, which is an extension for Firefox which allows to modify a web page once rendered with a simple javascript file.

To install it you’ll first need to have GreaseMonkey installed and activated (a little monkey face on Firefox’s status bar), then click on this link satkeystringconversor.user.js

Here is the highlighted source code so you can review it easily. It’s a pretty simple script which traverses the DOM performing regular expression tests on text nodes and converting the matched strings into span elements with an onclick behaviour.

// ==UserScript==
// @name           Sat key string conversor
// @namespace      http://pollinimini.net
// @description    Converts satelite key strings from hex to dec or vice versa
// @include        http://www.satscreen.ws/forum/*
// @include      https://www.blogger.com/*
// @include      http://floresd.blogspot.com/*
// @include      http://galeon.com/tusflores/*
// ==/UserScript==
function HEXDEC ( node ) {

  function hex2dec(hex) {
    var dec = [],
      re = /([0-9A-Za-z]{2})\s*/g|>,
      m,
      conv;
    while (m = re.exec(hex)) {
      conv = parseInt(m[1], 16);
      dec.push( (conv < 100 ? ( conv < 10 ? '00' : '0' ) : '') + conv );
    }
    return dec.join(' ');
  }

  function dec2hex(dec) {
    var hex = [],
      re = /([0-9]{3})\s*/g|>,
      m,
      conv;
    while (m = re.exec(dec)) {
      conv = (m[1]-0).toString(16).toUpperCase();
      hex.push( conv.length < 2 ? '0'+conv : conv );
    }
    return hex.join(' ');
  }

  function swapHexDec( e ){
    var target;
    if (!e) var e = window.event;
    if (e.target) target = e.target
    else if (e.srcElement) target = e.srcElement
    if (target.nodeType === 3) target = target.parentNode;
    var tmp = target.firstChild.nodeValue;
    target.firstChild.nodeValue = target.getAttribute('hexdec');
    target.setAttribute('hexdec', tmp);
    if (target.className === 'hexdec')
      target.className = 'dechex';
    else
      target.className = 'hexdec';
  }


  // if no node is specified then start processing on the page body
  node = node || document.body;

  var skipRe = /^(script|style|textarea)$/i|>;
  var re = /((?:[0-9A-Ha-h]{2}\s*){6,})|((?:[0-9]{3}\s*){6,})/g|>;
  // get all nodes from dom
  var nodes = node.all || node.getElementsByTagName('*');
  var i, cnode, span;

  // loop thru all the nodes
  for (i=0; i<nodes.length; i++) {
    // skip if it has no child nodes, it's already processed or the tag is not valid
    if (!nodes[i].childNodes.length ||
      nodes[i].hasAttribute('hexdec') ||
      skipRe.test(nodes[i].tagName)
    )
      continue;

    // loop thru all children
    cnode = nodes[i].childNodes[0];
    while (cnode) {
      // we just care about text nodes
      if (cnode.nodeType === 3) {
        // loop thru all regex matches
        while (m=re.exec(cnode.nodeValue)) {
          // if there is text before the match add it on its own node
          if (m.index > 0)
            cnode.parentNode.insertBefore(
              document.createTextNode( cnode.nodeValue.substr(0, m.index) ), cnode
            );
          // create a new span node for the key string
          span = document.createElement('SPAN');
          // if the first capture parenthesis is found then it's in hex format
          if (m[1]) {
            span.className = 'hexdec';
            span.setAttribute( 'hexdec', hex2dec(m[0]) );
          // otherwise it is in decimal format
          } else {
            span.className = 'dechex';
            span.setAttribute( 'hexdec', dec2hex(m[0]) );
          }
          span.setAttribute( 'title', 'Click to swap betwen hex and decimal notations' );
          span.appendChild( document.createTextNode( m[0] ) );
          //span.onclick = swapHexDec;
          span.addEventListener( 'click', swapHexDec, true );
          cnode.parentNode.insertBefore( span, cnode );

          // remove the already processed text from the node
          cnode.nodeValue = cnode.nodeValue.substring( m.index + m[0].length );
          // reset the regex text pointer
          re.lastIndex = 0;
        }
      }
      // point to next children or null
      cnode = cnode.nextSibling;
    }
  }
}

window.addEventListener( 'load', function () { HEXDEC() }, true );

function addGlobalStyle(css) {
    var head, style;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
}
addGlobalStyle( '\
  .hexdec, .dechex { \
    cursor: hand;\
    cursor: pointer !important;\
    border-bottom: 1px dotted #888;\
    padding-left: 32px;\
    background: url(http://pollinimini.net/temp/hex.png) no-repeat left;\
  }\n\
  .dechex {\
    background: url(http://pollinimini.net/temp/dec.png) no-repeat left;\
  }');

By default the following sites are enabled (you can configure it for whatever sites you need):

  • http://www.satscreen.ws/forum/
  • http://floresd.blogspot.com/
  • http://galeon.com/tusflores/
  • https://www.blogger.com/

It uses a neutral blue coloring for the styling which shouldn’t break most web designs. The images are served from my own server, so they aren’t very reliable, don’t be afraid if one day they stop showing :)