Surfterminal mit Linux

Wenn man einen Rechner im öffentlichen Raum als Browserterminal bereitstellen will, gibt es hauptsächlich die Anforderung, dass die User keine privaten Daten hinterlassen und am System so wenig wie möglich verstellen.

Es gibt verschiedenste Lösungen für diesen Zweck, fertige Linux-Distributionen oder spezielle Internet-Café Software, die Windows-Rechner so abschottet, das man noch nicht mal einen Explorer aufbekommt.

Für die beiden vom Freifunk betriebenen Surfterminals habe ich eine extrem simple Lösung gewählt. Die Rechner verrichten seit etlichen Monaten ohne Probleme ihren Dienst, obwohl es in den Kneipen schon etwas rauher zugeht.

Zunächst wird auf den Rechner die Linux-Distribution der Wahl installiert. Ich verwende Ubuntu, aber darauf kommt es nicht an. Es werden zwei Benutzer eingerichtet: ein administrativer („tresen“) und ein unpreviligierter („gast“). Achtung, bei Ubuntu ist der erste, bei der Installation eingerichtete User ein previligierter User (mit sudo-Rechten). Also erst „tresen“ und dann „gast“ einrichten und hinterher nochmal die /etc/sudoers überprüfen.

Man loggt sich zunächst als „gast“ ein und richtet den Browser so ein, wie man es gerne für die Gäste hätte: Adblocker, keine Cookies und Passwörter speichern, Startseite ect. Die Startseite für den Browser zeigt in unser Wiki, die Kneipengäste können dort dann eigene Links ablegen und so die Startseite etwas nach ihren Bedürfnissen anpassen. Der Webbrowser wird als Autostart-Applikation eingerichtet (System -> Preferences -> Sessions -> Startup Programs). Dann loggt man sich als „tresen“ ein und richtet den Anmeldungsmanager so ein, dass „gast“ beim Rechnerstart automatisch eingeloggt wird.

Jetzt kommt der interessante Teil: das Script pack_guest.sh verpackt das Home-Verzeichnis vom Gastuser in eine .tar-Datei:

#!/bin/sh
#
# Erstellt ein neues Template (gast_home.tar.gz) aus dem aktuellen gast
# Homeverzeichnis. Dieses Script sollte nur ausgeführt werden, wenn die
# Änderungem am gast-User dauerhaft gespeichert werden sollen.
#
# siehe http://wiki.freifunk-potsdam.de/index.php?title=Olga-Surfstation
if [ `whoami` != "root" ]; then
  echo "Du musst root sein, um das Script auszufuehren! Schau Dir bitte die"
  echo "Doku auf unserer Webseite an:"
  echo "http://wiki.freifunk-potsdam.de/index.php?title=Olga-Surfstation"
  exit 1
fi
 
#
DATE=`date +%Y%m%d_%H%M%S`
TARGET=/home/tresen/Surfstation/gast_home.tar.gz
 
# backup vom alten $HOME anlegen...
if [ -e $TARGET ]; then
  mv -v $TARGET  /home/tresen/Surfstation/gast_home_$DATE.tar.gz
fi
 
cd /
tar czf /home/tresen/Surfstation/gast_home.tar.gz /home/gast

Dieses Script ruft man einmalig auf und findet dann in /home/tresen/Surfstation die Datei gast_home.tar.gz. Dieses Template kann nun immer ausgepackt werden, wenn der Rechner startet. Das erledigt das Script unpack_guest.sh:

#!/bin/sh
#
# stellt den gast-user aus dem vorgefertigten Template (gast_home.tar.gz)
# wieder her. Das ist das Standard-Script, das bei jedem Booten ausgefuehrt
# wird. siehe
# http://wiki.freifunk-potsdam.de/index.php?title=Olga-Surfstation
#
if [ `whoami` != "root" ]; then
  echo "Du musst root sein, um das Script auszufuehren! Schau Dir bitte die"
  echo "Doku auf unserer Webseite an:"
  echo "http://wiki.freifunk-potsdam.de/index.php?title=Olga-Surfstation"
  exit 1
fi
 
rm -rf /home/gast
cd /
tar xzf  /home/tresen/Surfstation/gast_home.tar.gz
 
# falls das Passwort zurueck gesetzt wurde...
echo "gast:gast" | chpasswd

Jetzt muss man nur noch dafür sorgen, dass dieses Script bei jedem Bootvorgang ausgeführt wird. Eine Zeile in /etc/rc.local genügt:

/home/tresen/Surfstation/unpack_guest.sh

[Update] (12.11.09): Mir ist gerade aufgefallen, dass es mit Upstart zu einer Race-Condition kommt. Es ist einfach nicht definiert, wann das Script unpack_guest.sh ausgeführt wird und das führt zu sehr merkwürdigen Effekten.

Wenn man also eine Distribution mit Upstart verwendet (z.B. Ubuntu 9.10 „Karmic Koala“ oder später), muss man den Aufruf des unpack_guest.sh Scriptes im Upstart-System vor den gdm legen. Entweder man definiert einen eigenen Dienst oder man fügt das Script als pre-start Script in /etc/init/gdm.conf ein:

pre-start script
    # unpack the guest account home directory
    /home/tresen/Surfstation/unpack_guest.sh
end script

[/Update]

Mir gefällt an diese Lösung, dass wir damit absolut keine Arbeit haben. Die einzigen Probleme sind Hardwareschäden, also wenn wiedermal Bier über die Tastatur gekippt wurde. Das System an sich läuft aber nahezu wartungsfrei. Man muss sich halt alle paar Monate (idealerweise remote) einloggen und die fälligen Updates einspielen.

Schnelle Übersetzung im Safari

Ich lese viel englische Texte und bin dank „Finer Things in Mac“ auf ein Feature gestoßen, das mir beim Lesen sehr weiterhilft: der Shortcut CTRL + CMD ⌘ + D.

Dictionary.appDamit kann man in jeder Cocoa-Applikation (z.B. Safari) das Wort unter dem Mauscursor im Mac OS X eingebauten Wörterbuch nachschlagen. Als Standard wird das New Oxford American Dictionary mitgeliefert, das nur von Englisch nach Englisch „übersetzt“. Zum Glück gibt es Abhilfe: das BeoLingus Dictionary-Plugin Deutsch/Englisch ermöglicht die Übersetzung von Englisch nach Deutsch und umgekehrt.

Nach der Installation des Plugins und dem Neustart der Dictionary-Anwendung muss jetzt nur das Deutsch/Englisch Wörterbuch als erstes Wörterbuch festgelegt werdem. Dieses wird bei CTRL + CMD ⌘ + D verwendet, die anderen Wörterbucher sind Fallback, wenn das Wort nicht gefunden wird. Die bevorzugte Reihenfolge der Wörterbücher kann man in den Einstellungen von Dictionary.ap festlegen. Einfach das „German-English“ Wörterbuch vom Ende der Liste an den Anfang der Liste ziehen…

Dictionary Settings

…und schon muss man nie wieder die Anwendung wechseln, nur um ein Wort nachzuschlagen:

Dictionary

Besserer Maschinencode mit clang

LLVM ist das nächste große Ding. Nach all den Jahren, wo man es hingenommen hat, dass der gcc so ist, wie er ist und man heimlich denkt, dass der Microsoft Visual C++ Compiler doch irgendwie besser war, taucht plötzlich LLVM mit clang im Gespann auf und schickt sich an die Welt zu erobern.

Wer von LLVM noch nie etwas gehört hat, dem kann ich einen ganz wunderbaren Podcast empfehlen. Kurz gesagt: die Low Level Virtual Machine ist eine Compiler Infrastruktur, ein Compiler-Baukasten. Es gibt verschiedene Frontends, die aus unterschiedlichen Eingabesprachen (z.B. C, Objective C, Fortran, in Ansätzen auch C++ ) einen Bytecode generieren. Dieser Bytecode wird optimiert und im letzten Schritt mittels eines Backends in nativen Maschinencode für eine konkrete Architektur übersetzt.

Diese Verarbeitung ist nicht etwa tief im Compiler verborgen, sondern kann ganz praktisch mittels Pipes zusammengebaut werden:

$ clang-cc file.c -emit-llvm -o - | llvm-as \
  | opt -std-compile-opts | llc > file.s

Neben dem Satz an Standard-Optimierungen kann man sich noch mehrere Dutzend Spezial-Optimierungen die heraussuchen, wenn man denkt, dass das eigene Programm die nötig hat. Optimierungen kosten natürlich Zeit und so ist man eher geneigt während der Entwicklung wenige Optimierungen zugunsten schneller Compilerzeiten zu wählen, während man im Release-Stadium mehr Optimierungen wählt um die Performance zu optimieren.

Natürlich möchte man nicht in all seine Makefiles jetzt auf solche Pipe-Orgien umstellen. Es gibt zum Glück ein „drop in replacement“ für den gcc: clang. Man muss nur noch an einer Stelle im Makefile die gcc-Definition durch clang ersetzen – fertig. Alle Parameter werden verstanden, Compiler-Parameter übernommen – so unkompliziert, dass man nur noch staunen kann:

# CC=gcc
CC=clang
 
$(CC) -o binary source.c $(CFLAGS) $(IFLAGS)

Seit dem Podcast zu LLVM nagt in meinem Kopf die Idee, das ganze im aktuellen Projekt zu testen. In den beiden letzten Mobile Macs Sendungen war clang ebenfalls Thema, was dazu führte, dass heute das LLVM-Virus bei mir ausgebrochen ist 😉

Ich habe also das aktuelle Projekt (365.000-Zeilen C-Code) genommen und genau eine Zeile im Makefile geändert. Und es lief ohne Probleme. Ok, ich habe noch einen Fehler in unserem Makefile gefunden, aber dafür kann ja clang nichts. Die absolut problemlose Umstellung hat mich schon überrascht.

Aber warum sollte man dem gcc untreu werden, was bringt einem clang konkret? Da wären zunächst aussagekräftige Warnungen. Ich liebe Warnungen und predige bei jeder Gelegenheit wie wichtig es ist, auf die Warnungen vom Compiler zu hören. Das ist immer der Moment, in dem die Kollegen plötzlich etwas wichtigeres zu tun haben … 😉 clang spuckt Warnungen aus, mit denen man wirklich etwas anfangen kann:

src/source.c:457:15: warning: pointer types point to integer types with different sign passing 'unsigned char *', expected 'char const *restrict' [-Wpointer-sign]
        fputs(pbuffer, stdout);
              ^~~~~~~

Dagegen die Meldung vom gcc:

src/source.c:457: warning: pointer targets in passing argument 1 of ‘fputs’ differ in signedness

Dann wäre noch das Thema Performance. Es gibt Aussagen wie „OpenSSL wird 10% schneller“ (letzte MM-Sendung). Das macht schon neugierig und ich werde in der nächsten Woche auf jeden Fall ein paar Benchmarks durchführen um dem auf den Grund zu gehen. Jede Anwendung ist anders und bei unserem Projekt muss man erstmal sehen, was es wirklich bringt.

Wenn man aber „einfach so“ mehr Performance erhält, ist das ein hoch interessantes Thema. Ein Kunde von uns lastet mit unserer Anwendung eine 8-Core Maschine voll aus. Aufgrund gesteigerter Datenmengen wird diese Maschine bald zu klein sein. Wenn wir ihm sagen können „behalte Deinen Hobel, wir haben noch ordentlich etwas rausgeholt“ ist das für den Kunden natürlich ein Gewinn. Er kann die Hardware länger nutzen und spart Mirgrationskosten. Für uns ist das eher schlecht, weil wir am Lizenzupgrade nichts verdienen … aber ich bin Techniker und kein Verkäufer 😉

Stacktrace gefällig?

Gelegentlich braucht man einen Stacktrace. Ich bin heute über ein Problem gestolpert, bei dessen Lösung mir ein Stacktrace sehr helfen würde.

20090907_dddlogoEine unserer Bibliotheken kümmert sich um Speichermanagement. Das sind kleine Wrapper um malloc / free, die Buchhaltung über den Speicher führen und bei Fehlern entsprechende Meldungen ausgeben. Also der übliche Weg für das Speichermanagementproblem in C, es gibt duzende Lösungen die ähnlich funktionieren.

Das Problem heute war, dass Speicher freigegeben werden sollte, der nie allokiert war oder schon einmal freigegeben wurde. Er war auf jeden Fall nicht mehr als belegt gekennzeichnet und konnte somit nicht freigegeben werden. Programme ohne solch ein Speichermanagement würden an dieser Stelle abstürzen, bei uns taucht nur eine Meldung im Log auf.

Diese Meldung war mein Startpunkt für die Suche. Die Aufrufe der free-Wrapperfunktion sind jedoch in vielen Sourcefiles auf tausenden Zeilen Code verstreut. Wie soll man dort den einen Aufruf finden, der die Ursache für die Meldung ist?

Genau: ein Stacktrace muss her. Der schmutzige Weg wäre, das Programm mutwillig zum Absturz zu bringen. Dann kann man sich aus dem core-File den Stack rauspopeln und weiss, woher der Aufruf kommt.

Es gibt jedoch etwas viel schöneres: backtrace() aus der glibc. Mit ein paar Zeilen Code kann man an jeder beliebigen Stelle des Programms einen Stacktrace erzeugen:

void *array[10];
size_t size;
char **strings;
size_t i;
 
size = backtrace (array, 10);
strings = backtrace_symbols (array, size);
 
printf ("Obtained %zd stack frames.\n", size);
 
for (i = 0; i < size; i++)
   printf ("%s\n", strings[i]);
 
free (strings);

Ich habe also in der free-Wrapperfunktion backtrace() eingebaut und konnte mir den Stacktrace für den Fehlerfall ausgeben. Im Log erhält man dann etwa diese Ausgabe:

yourbinary [0x80b9e0c]
yourbinary [0x80b9f02]
yourbinary [0x8054abd]
yourbinary [0x805124f]
yourbinary [0x8050078]
yourbinary [0x808d6f3]
yourbinary [0x804bd42]
yourbinary [0x804b04e]
libc.so.6(__libc_start_main+0xe5) [0xb7d0f775]
yourbinary [0x804a701]

Ok, das sieht schon mal gut aus 😉 Jetzt muss man nur noch yourbinary in den ddd laden um die Speicheradressen in Codezeilen umzuwandeln – et voilà: schon ist die bösartige Zeile Code identifiziert.

har2009: angekommen

Ich probiere mal dieses Video-Dings aus. Dann muss ich auch nicht so viel tippen 😉 Bin gerade zu müde noch einen richtigen Podcast draus zu machen, das kommt später.

Update: hatte das Video versehentlich auf „private“ gestellt, jetzt sollte es funktionieren.

Dieses Twitter-Ding

…ist dann doch ganz interessant. Natürlich gilt auch hier: es ist das, was Du draus machst. Mit 140 Zeichen zu bloggen ist wie mit einem 50mm-Objektiv fotografieren. Die scheinbare Limitierung eröffnet neue Möglichkeiten.
Inzwischen ist es für mich auch eine ernsthafte Kommunikationsplattform geworden. Manche Dinge, die ich für zu kurz/unrelevant zum Bloggen halte, landen nun bei Twitter.
20090531_twitterific_logoWas man draus macht, heisst in erster Linie, wem man folgt, wessen Tweets man liest. Klar kann man hauptsächlich Leute lesen, die Befindlichkeiten, persönliches oder lustiges twittern. Das ist dann aber Unterhaltung. Ich bin eher ein Informationsjunkie und unfollowe radikal Leuten, die (für mich) unrelevantes zwitschern.
Ich glaube nicht, dass RSS tot ist. Es ist für mich nach wie vor das wichtigste Medium um mir Spezialinformationen (nerdiges, fotokram, …) auf den Monitor zu spülen. Bei Twitter bekommt man sehr schnell mit, wenn wieder eine Sau durchs Dorf getrieben wird. Es kann eben alles sein: belangloser Chat und gleichzeitig ein Medium das 100.000e mobilisiert.

Briefwahl für die Europawahl beantragen

Update: das Zertifikat wurde inzwischen erneuert, damit ist der sicherheitsrelevante Teil dieses Artikels hinfällig. Die Usability ist natürlich weiterhin total kaputt.

… das sollte einfach sein, wenn man dem Landeswahlleiter glauben mag:

Für die Antragstellung kann auch der elektronische Wahlscheinantrag aus dem Internetangebot des Landeswahlleiters zur Europawahl 2009 unter www.wahlen.brandenburg.de genutzt werden. Das vom Antragsteller online ausgefüllte Formular wird über die „Senden“-Funktion an das hier hinterlegte elektronische Postfach seiner Heimatgemeinde weitergeleitet. Von dort erhält er dann die angeforderten Unterlagen.

Unter www.wahlen.brandenburg.de gelangt man über Wahlen -> Europawahlen -> Europawahl am 7. Juni 2009 zu einer Dokumentenübersicht.
Das Wort „Briefwahl“ sucht man auf der Seite vergeblich. Der Antrag verbirgt sich hinter der kryptischen Bezeichnung „Elektronischer Wahlscheinantrag
Hier kann man den Landkreis und die Gemeinde auswählen um dann mit dem Link „Weiter zu den Formularen“ auf folgendes Problem zu stoßen:

20090524_abgelaufen

Na prima, kurz vor der Europawahl, genauer gesagt am 22.05.2009 um 19:25 Uhr ist das SSL-Zertifikat für den Server secure.service.brandenburg.de abgelaufen. An dem Server hängen bestimmt noch mehr Services als nur das Briefwahlformular. Aber ist ja nicht so schlimm, ist ja alles sicher. Es geht ja nur um Wahlunterlagen.

Lieber Landeswahlleiter, tritt Deinem Webmaster bitte mal in den Hintern. Wenn man ein Zertifikat mit einer Gültigkeit von 12 Monaten kauft, hat man sich rechtzeitig um eine Verlängerung zu kümmern. Oder war dafür plötzlich das Budget alle?

Aber wartet, es kommt noch besser… 🙁 Natürlich kann man ein abgelaufenes Zertifikat im Browser akzeptieren und die Seite trotzdem besuchen. Tut man das, kommt man auf eine Seite im CMS, die unter „Wahlscheinantrag für die Europawahl am 7. Juni 2009“ tatsächlich, beinahe, nur noch einen Klick entfernt… das gesuchte PDF verlinkt. Man muss auf der darauf foldenden Seite noch den Button „öffnen“ drücken.

Dieses PDF ist eins mit Formularen. Adobe hat so viel Features und Javascript-Foo in seinen Reader eingebaut, dass man dort PDF-Formulare ausfüllen und über das Netz absenden kann. Warum ein einfaches HTML-Formular für den Zweck nicht genügt, weiss wahrscheinlich auch nur der Amateur, der das PDF zusammengeklickt hat.

Im PDF steht ein netter Hinweis, der aber so nicht korrekt ist:

Bitte beachten Sie, dass Ihre Daten unverschlüsselt übermittelt und nur vorübergehend gespeichert werden.

20090524_wohin_wird_das_formular_gesendet

Das Formular wird entgegen dem Hinweis im PDF natürlich verschlüsselt und abgesichert via SSL an den Server gesendet. Und daran wird das ganze auch scheitern, wie wir gleich sehen. Zuerst muss man das Senden der Formulardaten nochmal explizit im Reader bestätigen:

20090524_security_warning

Allerdings ist der Acrobat Reader etwas pingeliger was die Gültigkeit von SSL-Zertifikaten angeht:

20090524_double_fail

#fail Der Reader verhält sich korrekt und verweigert eine SSL-Verbindung mit einem abgelaufenen Zertifikat. Das Beantragen der Briefwahlunterlagen ist auf diesem Wege also überhaupt nicht möglich.

Natürlich kann man die Briefwahlunterlagen auch formlos per Brief oder e-Mail beantragen, jedoch wundere ich mich, dass der Weg über die offizielle Webseite des Wahlleiters so umständlich, benutzerfeindlich und fehlerhaft ist. Haben sich nicht alle Behörden e-Government auf die Fahnen geschrieben? Warum ist das alles so stümperhaft implementiert? Bin ich der einzige, der beim Benutzen der Seite permanent den Kopf auf die Tischplatte schlägt?

Sicherheit ist kein nice-to-have Feature, gerade bei allen Angelegenheiten die mit Wahlen zu tun haben, ist eine funktionierende Sicherheitsinfrastruktur ein absolutes Muss-Kriterium.

Ich hoffe das Kontaktformular auf der Seite funktioniert und unser Hinweis auf das abgelaufene Zertifikat erreicht die richtigen Personen rechtzeitig um das Problem vor der Wahl zu beheben.

HFS+ unter Linux beschreiben

Ich habe heute zu meinem Erstaunen festgestellt, dass man HFS+Volumes – dem Fall meine externe USB-Platte – nicht unter Linux beschreiben kann. Nachdem ich google eine Weile mit Suchbegriffen („Read only filesystem“ „hfsplus“) beworfen hatte, kam auch ans Licht, woran das liegt.

Linux kann schon HFS+-Volumes beschreiben, allerdings nicht, wenn diese journaled sind. Die Lösung, das Journal abzuschalten, ist für mich akzeptabel. Unter Mac OS X geht das am schnellsten auf der Kommandozeile:

1
$ sudo /usr/sbin/diskutil disableJournal /Volumes/BACKUP

Mein kleiner Bauchladen

iMac 20inch

Kurz und schmerzlos: iMac white, 20 Zoll Display, keine Pixelfehler, 2 GHz core duo, 2 GB Ram, 250 GB Festplatte, mehr technische Details bei everymac. Tastatur der Marke „Krümelschublade“ und die tolle magnetische Apple Remote sind natürlich dabei.

War mein treues Arbeitspferd in den letzten 2.5 Jahren und ist nach wie vor eine geniale Surf- Multimedia- und Photoshop-Maschine. Ich trenne mich nur unter großen Schmerzen davon, ein realistisches Gebot per Mail kann meine Trauer jedoch mildern. Ansonsten kommt der Rechner Montag zu ebay.

Reinstall

Nachdem mein Mac permanent an der Kotzgrenze war, habe ich heute kurzerhand Mac OS neu installiert. Man sollte ja nicht denken, dass soetwas notwendig ist und Erfolg bringt. Aber die Kiste ist jetzt genau 3 Jahre alt, hat diverse Software übergebügelt bekommen, ein Upgrade von 10.4 auf 10.5 hinter sich und war bei der täglichen Arbeit dauernd am swappen.

Also DVD rein und alles neu macht der Mai. Interessant finde ich, wie schnell man wieder arbeitsfähig ist. Einerseits, weil natürlich der meiste Kram sowieso im Netz liegt, aber auch, weil ich schätzungsweise nur 20% der installierten Applikationen genutzt habe. Der Rest fällt in die Kategorie „einmal ausprobiert, nie wieder angefasst“.

Ich habe deswegen auch nicht das Timemachine-Backup zurückgespielt, sondern mir selektiv die Daten wieder geholt, die ich wirklich brauche. Ansonsten bestände die Gefahr, sich den unbekannten Speicherfresser gleich wieder an Board zu holen.

istatsmenuCool auch, dass man sich die vormals installierten Anwendungen einfach wieder vom Backup mit dem Finder zurückkopieren kann. Würde ich alle Programme nochmal downloaden müssen, wäre ich jetzt noch lange nicht fertig. Aber so: drag, drop fertig.

Das Resultat ist ziemlich überwältigend, nach 12 Stunden uptime und diversen Klickorgien ist nach wie vor 1 von 2 GB Speicher verfügbar. Das war vorher vielleicht der Zustand kurz nach dem Booten.

Einziger Nachteil: das Argument, warum ich unbedingt einen Mac Pro brauche, ist natürlich erstmal wieder vom Tisch 😉

Watermark export action for Adobe Lightroom

20090127_watermark_1I watermark my photos in my photoblog using a little script (yes, I know this…). My workflow so far was

  1. export the photos from Lightroom
  2. open finder, go to the export directory
  3. open a shell in the directory
  4. run my watermark-script for the exported pictures

Well, this is annoying. But there is a gentle solution: Platypus! This great piece of software turns every Shell/Python/Perl/Whatever script into a little Mac-Application which can be used as export action in Lightroom.

To create your own export action using Platypus, just open the application and point it to the script path using the „Select“ button. Platypus is smart and will fill in more essentials:

20090127_platypus_1

Now press the „Create“ button and select the Lightroom Export Actions directory. It is usually
/Users/yourname/Library/Application Support/Adobe/Lightroom/Export Actions
Open Lightroom, select the pictures you want to export and press the Export-button (or Command Shift E). At the bottom of the export dialog you find the postprocessing options. The „after export“ combobox should now display the newly created export action:

20090127_export_action

Now press „export“ and watch what happens:
20090127_exporting

That’s it. Great isn’t it? 🙂 Here is my watermark-script. It needs exiv2 and imagemagick:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/python
 
import sys
import re
import os
import subprocess
import string
import shutil
 
# path exiv2 executable
EXIVBINARY="/usr/local/bin/exiv2"
# path composite executable (from imagemagick)
COMPOSITEBINARY="/opt/local/bin/composite"
# watermark image
WATERMARKFILE="/Users/melle/Pictures/watermark/Watermark2.png"
 
for filename in sys.argv[1:]:
 
    if not os.path.exists(filename):
        print filename + " does not exist!"
        continue
 
    # extract some strings from the filename
    pathRe = re.compile( '^.*\/')
    plainFilename   = pathRe.sub( '', filename)
    baseFilename    = string.replace(plainFilename, ".jpg", "")
    newFilename     = "mark_" + plainFilename
    newMetaFilename = "mark_" + re.compile('\.[jJ][pP][gG]').sub('.exv', plainFilename)
 
    print "Tagging " + plainFilename
 
    # get the path - if available
    m = pathRe.search(filename)
    if m:
        pathname = m.group()
    else:
        pathname = ""        
 
    # backup metadata to exv-file
    p = subprocess.Popen(EXIVBINARY + " -f ex \"" + filename + "\"", shell=True)
    sts = os.waitpid(p.pid, 0)
 
    # mv "$BASENAME.exv" "$NEWMETAFILENAME"
    shutil.move(pathname + baseFilename + ".exv", pathname + newMetaFilename)
 
    # add watermark
    p = subprocess.Popen("/opt/local/bin/composite -unsharp 2.0x1.4+0.6+0.05 -dissolve 30 -gravity southeast -geometry +25+25 \"" + WATERMARKFILE + "\" \"" + filename + "\"  \"" + pathname + newFilename + "\"" , shell=True)
    sts = os.waitpid(p.pid, 0)
 
    # restore metadata
    p = subprocess.Popen(EXIVBINARY + " -f in \"" + pathname + newFilename + "\"", shell=True)
    sts = os.waitpid(p.pid, 0)
 
    # delete metadatafile
    os.remove(pathname + newMetaFilename)
 
    # open file in finder (mac only)
    p = subprocess.Popen("/usr/bin/open -a Finder \"" + pathname + "\"", shell=True)

25C3: Curse Of Silence

So, jetzt mal Hand hoch, wer ein Nokia E90 Communicator, Nokia E71, Nokia E66, Nokia E51, Nokia N95 8GB, Nokia N95, Nokia N82, Nokia N81 8GB, Nokia N81, Nokia N76, Nokia 6290, Nokia 6124 classic, Nokia 6121 classic, Nokia 6120 classic, Nokia 6110 Navigator, Nokia 5700 XpressMusic, Nokia E70, Nokia E65, Nokia E62, Nokia E61i, Nokia E61, Nokia E60, Nokia E50, Nokia N93i, Nokia N93, Nokia N92, Nokia N91 8GB, Nokia N91, Nokia N80, Nokia N77, Nokia N73, Nokia N71, Nokia 5500, Nokia 3250, Nokia N90, Nokia N72, Nokia N70, Nokia 6682, Nokia 6681, Nokia 6680 oder Nokia 6630 in der Hosentasche hat.

Aha. Na dann viel Spaß. Die Dinger können nämlich SMS vom Typ „e-Mail“ empfangen. Das sind SMS, die als erstes eine e-Mail Adresse enthalten. Das war aus Zeiten, als SMS/Mail Gateways noch populär waren. Wenn man solch eine SMS verschickt und am Anfang eine Mailadresse hinschreibt wird die beim Empfänger als eMail angezeigt (obwohl es ja eine SMS ist).

Der Buffer für die e-Mail Adresse ist 32 Zeichen lang.

Noch Fragen? Es genügt eine 33-Zeichen lange e-Mail Adresse in die SMS zu schreiben. Das Resultat ist, dass das angegriffene S60-Telefon keine einzige eingehende SMS mehr anzeigt. Egal wie viele hinterher gesendet werden. Auch nicht nach einem Reboot. Erst ein Factory-Reset hilft. Die Details stehen im Advisory. Es gibt auch ein Demo-Video:

Natürlich kann man als Operator (Vodafone, O2, t-mobile, e-plus) solche SMS filtern. Bis jetzt kann das aber nur t-mobile (vor 7 Wochen wurden die Operatoren angeschrieben). Und das funktioniert bei t-mobile auch nur für das Absenden.

Ich denke mal dieses Silvester wird lustig. „Hast Du meine SMS gar nicht bekommen?“ wird wohl häufiger gefragt werden. Und jetzt überlegt mal, wie oft die Leute die Software ihres Telefons updaten. Tja. Da wäre ja mal himmlische Ruhe in öffentlichen Verkehrsmitteln 😉

25C3: hangover

So langsam macht sich der Kongress bemerkbar, trotz konstanter Zufuhr von Mate werde ich noch nicht so richtig wach. Ich habe gestern den restlichen Abend im Hackcenter verbracht, teilweise Streams geguckt und teilweise am fonera geschraubt.
Sehr interessant war Squeezing Attack Traces und Stormfucker: Owning the Storm Botnet. Zuerst wurden konkrete Techniken gezeigt, wie man Malware analysieren kann. Die Zentrale Idee ist hier, statt eine Sandbox (Windows in einer VM) zu verwenden, die Requests unter Linux an Wine weiterzureichen. Dort kann man sich an jedem beliebigen Punkt reinhängen und die Requests der Malware auseinander nehmen. Schaut einfach mal auf die Honeytrap-Seite bzw. in die entsprechenden Aufnahmen.
In Stormfucker: Owning the Storm Botnet wurde das Storm Botnet vorgestellt und beschrieben, wie es funktioniert. Hier wurde – statt wie üblich eine Sandbox zu verwenden – der konkrete Botcode analysiert. Inzwischen scheinen die Tools auch einen großen Sprung gemacht zu haben, IDA Pro wurde schon mehrfach auf dem Kongress lobend erwähnt. Durch das Disassemblieren kam heraus, dass der Stormbot auf die Overnet-Architektur baut und als „Verschlüsselung“ lediglich XOR mit einem fixen Key verwendet. Man kann sich als Control-Server ausgeben und die Bots fernsteuern. Es wurde sogar ein Removal-Tool vorgestellt, mit dem man das Botnetz „von innen“ her säubern könnte. Da diese Aktion klar gegen deutsches Recht verstoßen würde, wurde das aber (noch) nicht durchgeführt.

Gerade habe ich mir Predictable RNG in the vulnerable Debian OpenSSL package angesehen, der Vortrag hat nochmal gut erläutert, warum eine auskommentierte Zeile Code einen so heftigen Effekt auf die Sicherheit von tausenden Servern hatte. Es wurden auch konkrete Angriffsszenarien und Gegenmaßnahmen gezeigt und der Vortragsstil war ebenfalls unterhaltsam 😉 Also einfach mal die Aufzeichnung anschauen, die Piratenbucht ist beim Auffinden der Mitschnitte sicherlich hilfsbereit.

25C3: hackcenter

20081229_flashing

Der fonera ist jetzt ein guter, dank der freundlichen Hilfe der Freifunker hier läuft er jetzt unter OpenWRT. Ich kämpfe noch damit, den OLSRd zum meshen zu bringen, aber das wird sicherlich noch.

Ich habe mir den Botnet-Vortrag als Stream angesehen: sehr geiler Shit wie Dennis sagen würde. Sobald der in der Piratenbucht ist, unbedingt saugen!