Donnerstag, 16. August 2012

Letzer Post...

Dies ist der letzte Post in diesem Blog. Das Blog wurde exportiert und zieht um, nachdem ich endlich meine Namensdomain bekommen habe... Die neue Adresse lautet: http://streibelt.de/blog Hintergründe zu der Entscheidung gibts entsprechend dort.

Freitag, 13. Juli 2012

Sicheres Passwort Hashing

Nachdem in letzter Zeit immer und immer wieder Webseiten vor allem dadurch auffallen, dass sie Passwörter im Klartext speichern, hier zwei Funktionen aus der User-Klasse eines meiner letzten Projekte...

Übrigens: Wenn Ihr bei Klick auf 'Passwort vergessen' von einer Webseite das Passwort im Klartext per Email zugesendet bekommt, macht man dort genau das falsch. Schaut dann mal in deren AGB oder Datenschutzbestimmung, ob sie dort behaupten die Passwörter zu hashen. Oft sind die nur Copy&Paste. Und bittet sie das Verfahren umzustellen. Oder schreibt Heise.

Der Code

Für die meisten Probleme gibt es Standards, so auch für das Passwort-Hashing. Es gibt also keinen Grund sich selbst mit Funktionen wie (der nicht mehr zu benutzenden) md5() und String-Operationen seine eigene crypt-Funktion zu schreiben.

Hier nun also eine Lösung mit php, weil die grade hier rumlag.

    /* Code Licence: Public Domain
     *
     * $this->pwhash wird in der DB gesichert bzw. daraus gelesen.
     * die Konfiguration in $_CONFIG sieht z.B. so aus:
     *
     * // Hier ist ein zufälliger Wert pro Webseite einzutragen:
     * $_CONFIG["pw_sitekey"]="897a-d21lk.a8q";
     * // Und hier der Hash-Also. sha1, sha512, NICHT md5!
     * $_CONFIG["pw_hashalgo"]="sha512";
     *
     */

    public function setPassword($password){
        global $_CONFIG;
        $site_key=$_CONFIG["pw_sitekey"];
        $algo=$_CONFIG["pw_hashalgo"];
        $nonce=uniqid();
        $hash = hash_hmac($algo, $password . $nonce, $site_key);
        $this->pwhash = $nonce.':'.$hash;
    }

    public function verifyPassword($password){
        global $_CONFIG;
        $site_key=$_CONFIG["pw_sitekey"];
        $algo=$_CONFIG["pw_hashalgo"];
        $nonce= strstr($this->pwhash, ':',TRUE);
        $hash = strstr($this->pwhash, ':',FALSE);
        $chash= ":".hash_hmac($algo, $password . $nonce, $site_key);
        return ($hash == $chash);
    }

Demo

Was kommt da nun also heraus? Dazu eine kleine Demo
        //Passwort
        $password="very secret";

        //Konfiguration:
        $site_key="12345";
        $algo="sha512";

        $nonce=uniqid();
        $hash = hash_hmac($algo, $password . $nonce, $site_key);
        $pwhash = $nonce.':'.$hash;

        //ausgabe zur Kontrolle
        echo "pwhash= $pwhash\n";

        //zu pruefendes Passwort:
        $check_password="very secret";

        $vnonce= strstr($pwhash, ':',TRUE);
        $vhash = strstr($pwhash, ':',FALSE);
        $chash= ":".hash_hmac($algo, $check_password . $vnonce, $site_key);

        if ($vhash == $chash){
            echo "passwords match!\n";
        }

Die Ausgabe bei übereinstimmenden Passwörtern:
pwhash= 50000b502b234:b038dfb61ba609604e7be78f3aa2cd84fb03970031f5e8d6f2eacc10542741dda5b7f41a716f3f78c305f6898d9b82838ce6b9df15dc94d00c37af393cc51de1
passwords match!

Passwort vergessen!

Wie setzt man das nun organisatorisch mit dem 'Passwort vergessen' Link zusamen? Ganz einfach. Wenn die Nutzer ihr Passwort vergessen können sie sich an ihre Emailadresse einen Link zusenden, mit dessen Hilfe sie auf der Webseite ihr Passwort selbst zurücksetzen können. Der Link enthält dabei ein zufällig erzeugtes Token und verliert nach Benutzung (erfolgreiches Ändern des Passworts) seine Gültigkeit.

Nachtrag: Und natürlich sollte der Link wenn er nicht benutzt wurde nach X Tagen ebenfalls invalidiert werden.

Sonntag, 1. Juli 2012

Rumms!

Rumms! Seit Jahren immer mal wieder versucht - heute geschafft ;) (Also das Photo zu machen bei Gewitter, nicht den Fernsehturm zu treffen...)

Sonntag, 30. Oktober 2011

U-Pad: Mikrofoneingan als Line-In

Wer kennt das nicht, da hat man eine USB-Soundkarte gekauft, weil der Eingang des Notebooks zu nah an der Festplatte vorbei geführt wird (sic!) und dann kann man an der Soundkarte kein Linepegen anlegen.

Nun, für diesen Fall möchte man ein Dämpfungsglied bauen. Ohne zu sehr auf die Details einzugehen, was die Anpassung angeht, hier ein einfacher Schaltplan um ein Mikrofoneingang zu einem Line-In zu machen.

Obacht: Dies ist für XLR, also symmetrische Signale, gedacht.

       ___ 7500
 o)---|___|-----o--------(o 
       R1       |                mit 2x7.5 und 1x150
LINE           | | 150     MIC   ergibt sich ein Teiler
 IN            |_| R3      OUT   verhältnis von 
       ___      |                15000:150 = 100:1 = -40dB
 o)---|___|-----o--------(o      Bitte 
       R2  7500                  Metallschichtwiderstände
                                 verwenden, die Rauschen nicht.

Für asymmetrische Signale sollte ein normaler Spannungsteiler funktionieren:

         ___15000
 o)-----|___|----o-----(o
                 |
                | | 150
IN              |_|          OUT
                 |
 o)--------------o-----(o

Sonntag, 31. Juli 2011

postfix: IP-Adresse des Absenders verbergen

Nach langer Zeit gibt es heute mal wieder einen kleinen Post aus der Sysadmin-Ecke.

Die Ausgangslage

Ein Benutzer liefert seine Emails mit Authentifizierung bei einem durch mich betriebenen Mailserver ein, der für die entsprechende Domain zuständig ist.

In den Headern dieser Mail wird nun die IP-Adresse auftauchen, von der aus die Email eingeliefert wurde. Dies kann die IP zu Hause sein, die von einem Bekannten oder die von einer Institution. Postet derjenige häufiger auf Mailinglisten kann man so schon ein Profil erstellen und bekommt auf jeden Fall heraus, dass er z.B. Emails von der Uni aus sendet, etc.

Dies möchte man nun verhindern - und das funktioniert mit postfix Bordmitteln sogar relativ einfach.

Mehr Information ist am Ende doch weniger

Zunächt müssen wir die entsprechenden Header erkennen können. Da bei allen nicht-authentifizierten Emails die IP-Adresse des einliefernden MTA im Header unverändert erhalten bleiben soll, schon um Spammer identifizieren zu können ohne extra in die Logs schauen zu müssen, brauchen wir einen Weg, die passenden Received:-Header zu erkennen. Dies erreichen wir, indem wir dem postfix sagen, dass er den Benutzernamen des Absenders auf dem Mailserver in den Header einfügen soll. Dies geschieht über die Anweisung smtpd_sasl_authenticated_header = yes in der Datei main.cf des postfix.

Unser header sieht nun ungefähr so aus:

Received: from [192.168.101.150] (guest123.guest.example.org [192.0.43.10])
  (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits))
 (No client certificate requested)
 (Authenticated sender: username)
 by mail.somedomain.tld (Postfix) with ESMTPSA id 32A59B1C032
 for ; Thu, 30 Jun 2011 12:36:07 +0200 (CEST)

Die hervorgehobene Zeile ist neu hinzugekommen und ermöglicht es uns im zweiten Schritt nach genau diesen Headern zu suchen.

pcre ftw!

postfix bietet dafür die Möglichkeit der header_checks. Damit kann man mittels (perl) regular expressions auf den Headern der Email arbeiten und Zeilen einfügen, Zeilen ändern und eigentlich vor allem Aktionen auslösen wie das Aufhalten einer Email, Abweisen, Weiterleiten, etc.

Wir benutzen diese Möglichkeiten, um auf der oben gezeigten Received:-Zeile ein paar Ersetzungen vorzunehmen.

Dazu stellen wir zunächst sicher, dass die main.cf des Postfix auch header checks aktiviert hat:

 smtpd_sasl_authenticated_header = yes
 ...
 header_checks      =  pcre:/etc/postfix/header_checks
 mime_header_checks =  pcre:/etc/postfix/header_checks

Nun koennen wir in der angegebenen Datei header_checks mit folgender Zeile das Umschreiben aktivieren:

/^Received:\ from (.*)\(.*\)(.*)\(Authenticated\ sender:\ .*\)(.*by mail\.somedomain\.tld.*)$/U  REPLACE Received: from $1 (Remote IP hidden) $2(Sender was authenticated on somedomain.tld) $3

Hinweis: Die Zeile ist relativ lang, beim Kopieren aufpassen sie komplett zu erwischen. Wichtig ist die Option U an der Regex, diese schaltet sie auf ungreedy. Siehe man pcre_table.

Der Name des Mailservers taucht hier nochmal auf, damit ich die Original-IP bei extern eingelieferten Emails nicht verwerfe - das kann zum Identifizieren von Spammern helfen, auch wenn die Header oft gefälscht sind.

Im Ergebnis sieht der Header der Email nun aus wie folgt:

Received: from [192.168.101.150]  (Remote IP hidden) 
 (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits))
 (No client certificate requested)
 (Sender was authenticated at somedomain.tld) 
 by mail.somedomain.tld (Postfix) with ESMTPSA id A36241184685
 for ; Fri, 29 Jul 2011 20:23:31 +0200 (CEST)

Wenn man die private IP auch noch entfernen möchte, kann man sich jetzt natürlich einen weiteren Header-check überlegen, der auf '\[.*\].*Remote IP hidden' triggert und diese ersetzt. Das kann im Einzelfall notwendig werden, wenn kaputte Antispam-Maßnahmen anderer Empfänger solche Emails ablehnen.

Wenn man misstrauisch ist fügt man ausserdem noch eine Zeile hinzu, die jedes Vorkommen von '(Authenticated sender: ...)' mit etwas belanglosem ersetzt, falls man unter allen Umständen die internen Nutzernamen geheim halten will.

Sonntag, 6. Februar 2011

Effizienter Desktop mit fluxbox

Nach langer Zeit mal wieder ein kleines Posting von mir. Diesmal zum Thema Organisation des Desktops bzw. Windowmanagers

Vor zwei Tagen bin ich auf der Suche nach einem neuen Windowmanager auf Anregung von Seba auf fluxbox umgestiegen. Flott, schlank, stark konfigurierbar. Auch wenn ich nach wie vor ein paar Gimmicks vermisse, habe ich Features entdeckt, die ich glaube ich nicht mehr missen will.

Dinge die ich vermisse

Der System-Monitor von Gnome war doch ganz praktisch. Man konnte in einem Panel die CPU-Auslastung sehen und den Speicherverbrauch. Aktuell habe ich nur die CPU-Auslastung beider CPUs ohne Unterscheidung in Nice, System und IO-Wait. Die wmaker-Docks sind mir zu groß und außerdem nicht im Panel. Ein 'swallow' wie damals beim fvwm2 wäre toll, um Anwendungen in das Panel einzubinden.

Die Arbeitsflächen lassen sich nicht zweidimensional anordnen, d.h. ich kann immer nur nach links und rechts, nicht nach oben und unten wechseln. Das war aber relativ effizient, um schnell zwischen Anwendungen zu wechseln. Eine Sache der Gewöhnung, hoffe ich.

Das Killer-Feature

Eines der Killer-Features schlechthin ist aber die Möglichkeit, beliebige Aktionen, per MacroCommand auch mehrere, auf Tastaturshortcuts zu legen.

Nicht nur, dass man damit Dinge wie das Maximieren oder Umschalten der Arbeitsflächen anpassen kann, man kann auch neue Funktionalität schaffen, zum Beispiel einer Anwendung eine Tastenkombination zuordnen und sie nur dann starten wenn sie noch nicht läuft.

Aktuell ist mein fluxbox nun so konfiguriert, dass Programme wie Firefox, Thunderbird, etc. eine Tastenkombination haben, die entweder auf die Arbeitsfläche mit der Anwendung umschaltet und sie anzeigt oder aber eine Dialogbox aufpoppt mit der Frage, ob sie gestartet werden soll. Zusätzlich ist den Anwendungen eine Arbeitsfläche und Größe fest zugeordnet, auf der sie starten sollen.

Läuft die Anwendung also noch nicht, startet sie unsichtbar auf ihrer Arbeitsfläche und ich kann dann später dorthin umschalten, sobald sie bereit ist.

Gerade das Umschalten zum Instant-Messenger oder Mediaplayer und wieder zurück zum Browser oder der IDE ist damit sehr schnell möglich.

Hinweis: Eventuell klappt das nur mit der aktuellen git-Version von fluxbox, da NextWindow unter Umständen nicht alle Workspaces durchsucht.

Hier die relevanten Auszüge:

~/.fluxbox/keys:
Mod4 C :Reconfigure
Mod4 F :If {Some Matches (class=Iceweasel)} {NextWindow (class=Iceweasel)}  {Exec ~/.fluxbox/bin/fbexec.sh iceweasel}
Mod4 G :If {Some Matches (class=Gmpc)     } {NextWindow (name=gmpc) (class=Gmpc)} {Exec ~/.fluxbox/bin/fbexec.sh gmpc }
Mod4 M :If {Some Matches (class=Icedove)  } {NextWindow (class=Icedove) } {Exec ~/.fluxbox/bin/fbexec.sh icedove}
Mod4 P :If {Some Matches (class=Pidgin)   } {NextWindow (class=Pidgin)  } {Exec ~/.fluxbox/bin/fbexec.sh pidgin }
Mod4 R :If {Some Matches (class=RSSOwl)   } {NextWindow (class=RSSOwl)  } {Exec ~/.fluxbox/bin/fbexec.sh ~/bin/RSSOwl.sh}
Anm: Mod4 ist die 'Windows'-Taste. Die Werte für class habe ich der apps-Datei entnommen, die fluxbox automatisch erweitert, wenn man mit der rechten Maustaste auf eine Titelleiste klickt und 'Remember' anklickt um Attribute wie den Workspace der Anwendung zu speichern. Alternativ geht auch xprop oder wmctl -l ~/.fluxbox/apps:
...
[app] (name=Navigator) (class=Iceweasel) (role=browser)
  [Workspace]   {5}
  [Dimensions]  {1198 682}
  [Position]    (UPPERLEFT)     {0 80}
[end]
...
~/.fluxbox/bin/fbexec.sh:
#!/bin/sh

#timeout returnes 0 (success) thus we have to use || here:
xmessage -center -buttons 'yes:1,no:0'  -timeout 5 "about to exec $@" || exec "$@"

Sonntag, 19. Dezember 2010

Fight global freezing!

Hier wird natürlich nicht versucht, Berlin eisfrei zu bekommen. Das Gebäude gehört (wohl) zu den Klimatechnikern, die Wärmetauscher für Lehrzwecke brauchen...