Archiv: 2011

OpenSSH und Putty Schlüssel Dateien

07. November 2011

OpenSSH und Putty Schlüssel Dateien
Eine Secure Shell oder SSH Verbindung herzustellen geschieht normalerweise einfach über den Terminal. In meinem Fall gab es da aber noch eine Schlüssel-Datei im PuTTY eigenen PPK Format. Sicher, es gibt PuTTY auch für Unix Systeme, aber warum den Terminal wechseln, wenn es eigentlich gar nicht nötig ist. Aber leider kann openSSH nicht mit den Putty eigenen Schlüssel-Dateien umgehen. Wie man das Ganze trotzdem zum Laufen kriegt – eine kurze Anleitung.

Zunächst muss man den Schlüssel konvertieren, dass geschieht mit dem Programm PuTTYgen. Unter Ubuntu installiert man das wie folgt:

$ sudo apt-get install putty-tools

Dann konvertiert man den Schlüssel, und speichert diesen unter dem .ssh-Ordner im Home-Verzeichnis ab.

cd /path/to/orginalkey/
puttygen orginalkey.ppk -O private-openssh -o mynewkeyfile.sec
mv mynewkeyfile.sec ~/.ssh/
chmod 600 ~/.ssh/mynewkeyfile.sec

Damit die Schlüssel auch akzeptiert werden, gelten bestimmte Zugriffsrechte für das .ssh Verzeichnis (700) und die darin liegenden Dateien (600). In dieser Form funktioniert der Schlüssel, und man kann sich verbinden:

ssh MyUserName@hostname.de -i ~/.ssh/mynewkeyfile.sec

Soweit so gut, nun kann man den Komfort noch erhöhen. Dafür legt man eine config Datei im .ssh Verzeichnis an, in dem man die Verbindungsparameter dauerhaft speichert:

sudo gedit ~/.ssh/config

Eine genaue Anleitung findet man auf der entsprechenden man-page von ssh_config. Hier ein einfaches Beispiel:

Host mySSHConnection
    HostName 123.456.789.0
    Port 980
    User MyUserName
    IdentityFile ~/.ssh/mynewkeyfile.sec
    DynamicForward 1234

Die letzte Anweisung emuliert per SSH einen SOCKS 5-Proxy, der in meinem Falle ebenfalls nötig war. Man muss in seinem Browser lediglich die Verbindung entsprechend anpassen, das geschieht im Firefox bspw. über Bearbeiten > Netzwerk > Einstellungen. Dort die Angabe für Manuelle Proxy Konfiguration, als SOCKS Host die 127.0.0.1 und als Port den Wert des DynamicForward eintragen. Jetzt kann man sich im Terminal über den folgenden Befehl per SSH mit dem Server verbinden:

ssh mySSHConnection

Wer auf der Unity Oberfläche von Ubuntu unterwegs ist, kann sich noch folgende Launcher Erweiterung ansehen: Gnome-Terminal Quicklist (auto-update from ssh config), damit kann man die in der Konfiguration gespeicherten SSH Verbindungen direkt in seinen Terminal Launcher integrieren.

Eine Lösung für die gleiche Problematik auf einem Mac findet man unter leadingedgescripts.co.uk.

Regex Mysterium

06. November 2011

Regex Mysterium
In any project, there will be a certain amount of unknown. This is the nature of our work. schreibt Ka Wai Cheung in the developer’s code. Bei der Frontend-Entwicklung beziehe ich diesen Satz zumeist auf die "große Unbekannte" – den Client (von der Hard- und Software bis hin zum Interaktionsverhalten), aber auch die Sprache JavaScript und ihre Implementationen bieten immer wieder echte Überraschungen.

Eine triviale Aufgabe: ein Datum validieren und mit einem anderen Datum vergleichen, dabei kann das Datum eine gewisse Varianz in der Reihenfolge und Schreibweise haben. Ich betrachtete kurz die bereits implementierte Bestandslösung für die Validierung und war erstaunt über das mühsame Arbeiten mit substr. Das kann man doch eleganter lösen: Ein regulärer Ausdruck für die Validierung, dient gleichzeitig der Zerlegung des Datums, um daraus dann ein Date Objekt für den Vergleich zu erstellen:

// eine Pruefung unter vielen, Abbruch der gesamten Pruefung wenn fehlerhaft...
proceed = false;
var date_test = [ '07-11-2011' , '05-11-2011' ];
var date_regexp = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/;
 
if( date_test[0].match( date_regexp ) &&
    date_test[1].match( date_regexp ) ) {
 
   temp = date_test[0].split( date_regexp );
   date_A = new Date();
   date_A.setFullYear( temp[3],  ( temp[2] -1 ) , temp[1] );
 
   temp = date_test[1].split( date_regexp );
   date_B = new Date();
   date_B.setFullYear( temp[3],  ( temp[2] -1 ) , temp[1] );
 
 // Datum A muss vor Datum B liegen
  if( date_A < date_B ) {
     proceed  = true;
  }
}
// Ende der Pruefung - nun Entscheidung...
alert( proceed ); // Test Ausgabe
...

Auf den ersten Blick schien alles zu funktionieren. Wie erwartet wird "false" ausgegeben - Task erledigt, Ticket schließen, Feierabend machen. Nächster Morgen - Ticket ist wieder auf: Die Erweiterung funktioniert nicht. Alle folgenden Prüfungen werden nicht mehr ausgeführt, unabhängig vom Datum. Kann nicht sein, ich hatte das Datum definitiv mehrfach verändert, um alle Variationen zu kontrollieren. Teste daraufhin die Anwendung im Firefox erneut - alles wie gewünscht, Screenshots an das Ticket gehängt, Rückmeldung. Geht Nicht! Noch ein Test, diesmal im Internet Explorer, und siehe da, im Internet Explorer bleibt proceed immer false.

Ein Fehler im regulären Ausdruck? Nicht wirklich, denn der match funktioniert cross-browser. Aber das Datum ist im Internet Explorer NaN während alle anderen getesteten Browser das korrekte Datum ausgeben. Scheitern tut das ganze am split. Laut Spezifikation kann die String Methode sowohl mit Zeichenketten, als auch regulären Ausdrücken umgehen. De facto gibt es da aber einige Unterschiede:

var test_string = 'a,b,c,,,d,e,f,g';
 
// Split mit Zeichenkette
// Erwartet: 9 -> Ergebnis ist 9
var test_a = test_string.split(',');
alert(test_a.length);
 
// Split mit regulärem Ausdruck:
// Erwartet: 9 -> Ergebnis ist im IE: 7
var test_b = test_string.split(/,/);
alert(test_b.length);

Die Methode split reagiert eindeutig anders als die Methode exec des RegExp Objektes. Ändert man das ursprüngliche Script wie folgt:

// eine Pruefung unter vielen, Abbruch der gesamten Pruefung wenn fehlerhaft...
proceed = false;
var date_test = [ '07-11-2011' , '05-11-2011' ];
var date_regexp = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/;
 
if( date_test[0].match( date_regexp ) &&
    date_test[1].match( date_regexp ) ) {
 
   temp = date_regexp.exec( date_test[0] );
   date_A = new Date();
   date_A.setFullYear( temp[3],  ( temp[2] -1 ) , temp[1] );
 
   temp = date_regexp.exec( date_test[1] );
   date_B = new Date();
   date_B.setFullYear( temp[3],  ( temp[2] -1 ) , temp[1] );
 
 // Datum A muss vor Datum B liegen
  if( date_A < date_B ) {
     proceed  = true;
  }
}
// Ende der Pruefung - nun Entscheidung...
alert( proceed ); // Test Ausgabe
...

Dann funktioniert diese Prüfung in allen Browsern. Aber warum? Wieso verhält sich der gleiche reguläre Ausdruck bei zwei Methoden so unterschiedlich? Steven Levithan beschreibt in seinem Artikel JavaScript split Bugs: Fixed! gleich eine ganze Reihe von Fehlern (die nicht nur den Internet Explorer betreffen), und liefert auch gleich eine Lösung, in dem er die ganze Methode überlagert. Auch wenn es in meinem Fall ausgereicht hat, die Methode einfach zu wechseln - dieses Verhalten bleibt ein Mysterium. Bedeutet es doch, dass da unterschiedliche Verabeitungsprozesse ablaufen. Wenn man bedenkt, dass reguläre Ausdrücke für viele ohnehin ein Buch mit sieben Siegeln darstellt, wie passend ist es da, dass es auch noch solche Sprach-Fehler gibt.

Seite 1 von 212