Cryptoparty in Siegen
Am 10.8. ist im Hackerspace Siegen eine Cryptoparty (die Seite habe ich eben ein bisschen überarbeitet). Man wird mich dort aller Voraussicht nach antreffen können.
Deutschland im Herbst - Arbeitende Presse wird erschossen
Etwa gegen zwei Uhr war ich in dieser Nacht im Auftrag der Nachrichtenagentur Ruptly TV, für die ich als Kameramann arbeite, vor dem amerikanischen Konsulat. Ich war gerade aus der nordirischen Hauptstadt Belfast zurückgekehrt, um in Frankfurt am Main diese Kunstaktion vor dem Konsulat zu filmen.
Schon bevor alles losging, war plötzlich ein Aufgebot von etwa 20 Polizisten da; einige uniformiert, andere in Zivil. Die Künstler waren gerade vorgefahren. Sie hatten Technik dabei, um Bilder an die Gebäudewand zu projizieren. Wie ich gehört hatte, ging es darum, mit Lichtbildern gegen die Überwachung des amerikanischen Geheimdienstes NSA in Deutschland zu protestieren.
Dann ging alles ziemlich schnell. Mehrere Polizeiwagen fuhren vor. Mit der Waffe in der Hand wurde ich aufgefordert, meine Kamera abzuschalten. »Kamera aus oder ich schieß’«, hieß es. Ich war schockiert, welche Zustände in bezug auf die Pressefreiheit in Deutschland herrschen. Zunächst dachte ich, vielleicht ist all das darauf zurückzuführen, daß ich nur einen litauischen Presseausweis bei mir hatte.
"Die USA sind krank"
Eine amerikanische Regierung, die ein Spitzelprogramm wie Prism absegnet, respektiert nichts und niemanden mehr. Sie lebt Allmacht aus, sie wähnt sich erhaben über den Rechtsstaat, im eigenen Land ohnehin und sogar im Ausland. Dass nun Obama so handelt, ist trostlos. Ginge es um die Regierung Bush, könnte man denken: Es ist halt Bush, der ist berechenbar, es gibt noch ein besseres Amerika. Nun wissen wir: Es gibt nur ein Amerika. Hat der einstige Harvard-Jurist Obama seine Reden von der Rückkehr der Bürgerrechte eigentlich geglaubt? Kann jemand so zynisch sein, die Heilung der Welt zu versprechen, dann auf diese Weise zu handeln und gleichsam xenophob zu erklären, es würden ja nur Ausländer abgehört? Martin Luther King und Nelson Mandela sind Obamas Vorbilder, was würden sie sagen?
Klaus Brinkbäumer im Spiegel. Und er hat völlig recht, auch mit dem Rest des Kommentars. Das bisschen Bewunderung für Amerika, das mit Obama wieder aufgekommen ist, ist mehr als zerstört, wenn sich ein Amerika selbst unter Obama so verhält.
ProcessWire taugt
Ich habe wenig Erfahrung mit CMSs wie Joomla, Drupal oder eben ProcessWire. Bei meinen Projekten braucht man sowas nicht und Serendipity will ja explizit kein CMS sein. Von daher ist es kein Wunder, dass ich auf Matthias Empfehlung hörte und ProcessWire zuerst anschaute, als ich jetzt doch mal eins brauchte. Ich bin dabei geblieben, und bin tatsächlich etwas begeistert von dem System.
Dabei ist das verwunderlich. Zum einen war meine ursprüngliche Vorstellung, dass ich mir ein fertiges Design nehme und das entsprechend meinen Vorstellungen abändere. Doch für ProcessWire fand ich überhaupt keine passenden Designs. Und das mitgelieferte war zwar halbwegs ansehnlich, aber es war nicht dahin zu bringen, wo die Seite am Ende hin sollte. Dann die technische Seite: PHP, Apache und MySQL - klassischer und unflexibler geht es nicht. Dazu kommt ein Template-System, das reines PHP statt einer geeigneten Templatesprache nutzt.
Obwohl mich auch Processwire nicht überzeugt hat, dass PHP für Templates nicht eine schlechte Idee sind, ist es genau dieses Template-System, was ich so toll fand. Denn Processwire ist nicht wegen genialem Code oder der Performance oder irgendwelchen internen Architektursachen toll. Es ist toll, weil es ein einfaches und mächtiges Konzept umsetzt, mit dem ich komplett frei meine Seite zusammenbasteln, dann ein komplett eigenes Design draufklatschen und dem Kunden trotzdem genug Struktur geben kann, dass er mit der Seite zurechtkommen sollte.
Jede Seite im Frontend ist ein Objekt namens Seite, bzw Page. Eine Page hat ein Template, und Templates haben Felder. Felder können verschiedenen Templates zugewiesen werden, ein Beispiel für eine Feld wäre eine Emaileingabe oder eine Liste von Bildern - sie sind also wiederverwendbar. Der Nutzer kann dann im Backend den Inhalt der Felder pro Seite(!) konfigurieren, und der per Hand zu schreibende PHP-Code des Templates kümmert sich darum, wie diese Inhalte dargestellt werden. Zusammen mit dem unschätzbar nützlichen Repeater-Modul, mit dem man mehrere Felder zusammenfassen und vom Nutzer vervielfältigen lassen kann, ist so jede denkbare Struktur konstruierbar.
Dazu kommt die API, ohne sie würde das Konzept nicht halb so gut funktionieren. Im Template hat der Programmierer Zugriff auf eine Sammlung von Funktionen und Objekten, mit denen nicht nur auf die Attribute und Funktionen und damit die Inhalte der Felder zugegriffen werden kann, sondern mit der auch andere Pages und Objekte aufgerufen werden können, und das mithilfe zumindest ein bisschen jQuery-ähnelnden Selektoren.
Wie gesagt, ich habe nicht viel Erfahrung mit CMSs. Es ist daher möglich, dass ich zumindest teilweise weniger ProcessWire selbst als vielmehr die Grundidee eines CMS toll finde. Doch andererseits weiß ich, dass wenn die anderen Systeme wie ProcessWire funktionieren würden, nicht so oft über Unflexibilität und Wartungshorror oder das fürchterliche HTML geflucht werden würde, das sie generieren. Und auch wenn ein explizit dafür gedachtes Blogsystem wie s9y weiterhin seine Vorzüge hat, ein System wie ProcessWire ist auch für solche Spezialisten eine ernstzunehmende Konkurrenz. Zu leicht ist vorstellbar, dass man damit auch leicht einen guten Blog bauen könnte - ein passendes Modulpaket gibt es sogar schon.
Mails in Gmail verschlüsseln mit Mailvelope
Mailvelope ist ein Browserplugin für Chromium, angekündigt ist eine Version für Firefox. In Wirklichkeit kann es mehr als Gmail, theoretisch sollte es mit allen Webmailhostern zurechtkommen können.
Wie kann man sowas sicher umsetzen, auf fremden Seiten sicher Texte schreiben? Mailvelope öffnet dafür eigene Fenster. Das Javascript von Gmail hat darauf keinen Zugriff, das stellen die Browser sicher. Man schreibt seine Mail also in einem eigenen Fenster, verschlüsselt sie per Knopfdruck und lässt den verschlüsselten Text in das reguläre Editorfenster einfügen. Gmail hat also den unverschlüsselten Text nie gesehen.
Ebenso bei der Entschlüsselung: Auch wenn die Standardeinstellung den Text direkt auf der Seite verschlüsselt, gibt es eine Option, dafür ebenfalls ein eigenes Fenster zu nutzen.
Die Konfiguration läuft über die Pluginoptionen. Da fehlt noch ein bisschen, z.B. das Hochladen des Keys auf einen Keyserver. Dafür sind die nötigen Funktionen da: Erstellen von Keys, Importieren von solchen und Auflisten derselben.
Was ich vermisse ist eine Suchfunktion, die mir automatisch den Public-Key der Person heraussucht, mit der ich gerade schreibe. Und das Widget zum Auswählen, für wen die Mail verschlüsselt werden soll, ist zwar benutzbar, aber nicht gerade intuitiv verständlich.
Zwei Bugs treten bei mir auf:
- Wenn Chromium im Autostart ist, laden die Pluginoptionen nicht
- Mein privater Key verschwindet nach einem Reboot
Die Bugs scheinen zwar nicht üblich zu sein. Doch für mich sie sind sehr schade, denn sie verhindern natürlich die Nutzung des Plugins. Davon abgesehen gefällt mir das Plugin sehr gut - es zeigt, wie einfach Mailverschlüsselung sein kann.
Und weil es auch mit roundcube funktionieren soll, könnte ich es einfach weiterbenutzen wenn ich von gmail wegwechsel.
PS: Fingerprint meines Schlüssels ist CF11F733, ein gpg --search
sollte ihn finden.
Dropbox verschlüsseln mit encfs
Konsequenzen aus der NSA-Überwachung zu ziehen ist derzeit eines der beherrschenden Themen hier. Dropbox als fremdgehosteter Dienst mit vollem Zugriff auf wichtige Daten musste also irgendwann in meinen Fokus geraten. Meine erste Tendenz war zu wechseln, auf aeroFS oder BitTorent Sync. Doch letztendlich nutze ich Dropbox für meine derzeitige Beschäftigung, mehrere Freigaben von Projekten sind derzeit aktiv und überhaupt hab ich den Account damals nur angelegt, damit ein schwedischer Forschers mir seine Mistral-Konfiguration freigeben konnte. Also bleibt Dropbox, aber ich brauche irgendeine Absicherung.
Genug der Motivation. Dropbox zu sichern ist einfach genug. Ich folge dem Konzept von Boxcryptor und nutze dafür - wie andere vor mir - encfs: Es wird ein Ordner Dropbox/encrypted angelegt, der verschlüsselte Dateien enthält. Ein anderer Ordner im Homeverzeichnis, Dropbox-decrypted, zeigt die entschlüsselten Dateien - ein mount plus Entschlüsselung. Wird etwas diesem Ordner hinzugefügt, wird es automatisch in Dropbox/encrypted verschlüsselt gespeichert und so von Dropbox gesynct, ohne dass Dropbox je die entschlüsselten Dateien sehen würde.
Dropbox verschlüsseln
Installiert werden muss das Paket encfs. Danach:
encfs ~/Dropbox/encrypted ~/Dropbox-decrypted
Dem Wizard folgen, wobei die Voreinstellung p völlig ok sein sollte. Passwort wählen. Fertig.
Unmounten geht mit fuserumount -u, mounten mit dem gleichen Befehl wie bei der Erstellung.
Automount
Nun soll das ganze natürlich noch automatisch beim Login ausgeführt werden Da gibt es verschiedene Wege, von pam_mount zu pam_encfs bis hin zu gnome-encfs.
Die Grundidee bei den pam-Modulen ist, beim Login das Passwort gleich nochmal zu nutzen um encfs auszuführen. Bei meinem momentan noch genutzten rungetty-Autologin keine Option. gnome-encfs dagegen speichert das Passwort in Gnomes Keyring und startet encfs per Gnomes Autostart, wobei ersteres generell auch ohne Gnome eine tolle Idee ist, nur dass bei mir dbus nicht und damit kein Keyring funktioniert.
Deswegen meine händische Lösung: Bei jedem Login wird per .icewm/startup ein Skript ausgeführt, das die Dropbox entschlüsselt. So sieht es aus:
#!/bin/bash i=0 decryptDropbox() { encfs --extpass="/usr/lib/openssh/gnome-ssh-askpass 'Decrypt Dropbox'" ~/Dropbox/encrypted ~/Dropbox-decrypted if [ $? != 0 ]; then zenity --title="encFS: mount failed" --info --text="The decryption failed" 0x0 let i++ if [[ "$i" -le 2 ]]; then decryptDropbox fi else notify-send "Dropbox" "successful decrypted" fi } decryptDropbox
Die benötigten Pakete sind ssh-askpass-gnome, zenity und libnotify-bin, was notify-send
beinhaltet und alternativ samt dem else-Zweig weggelassen werden kann.
Langsam eicht sich das Nährhörnchen. Die NSA-Verteidigung hat hiermit eine Mauer mehr.
NSA Enthüllungen - Die offizielle Liste
Snowden arbeitete für seine Enthüllungen dem Journalisten Greenwald zusammen, gab ihm einen Teil der Dokumente. Dieser hat eine Liste mit den gesammelten Enthüllungen zusammengestellt (via). Ein paar dieser offiziellen Enthüllungen, die uns betreffen:
- Prism warb damit, direkten Zugriff auf Server von Internetfirmen zu haben, darunter Google, Apple und Facebook
- Auf Befehl von Obama wurde eine Liste von Zielen für Cyberattacken zusammengestellt, Ziel: 'advance US objectives around the world'
- Boundless Informant wurde enthüllt, ein NSA-Visualisierungstool der Überwachungsdaten. Darin sieht man auch, welche Staaten wie stark überwacht werden:
Man beachte, Deutschland ist gelb (da klassifiziert als Angriffsziel und Partner dritter Klasse)
- GCHQ - britischer Geheimdienst - holt sich Daten direkt aus den Internetleitungen, die durch England laufen - darunter Facebooknachrichten und Emails. Diese werden mit der NSA geteilt
- Der Emailverkehr von Millionen von Brasilianern wird gesammelt, Greenwald nennt das "bulk collecting". Relevanz für uns: Brasilien ist auf der Heatmap grün, Deutschland ist gelb. Wenn die Map stimmt, wird Deutschland also noch stärker abgehört, noch mehr Mails als in Brasilien oder mehr als Mails abgefangen und gespeichert. Stimmt die Map nicht ist Brasilien trotzdem ein wahrscheinliches Beispiel dafür, was auch in Deutschland passiert.
- Microsoft hat besonders eng mit der NSA zusammengearbeitet, beschrieben im Guardian. Die Zusammenarbeit umfasst:
- Abfangen von Nachrichten, z.B. auf Outlook.com, unter Umgehung der konzerninternen (und nach außen beworbenen) Verschlüsselung
- Zugriff auf gespeicherte Daten wie Dokumente auf Skydrive, Mail auf Outlook
- Skype wird abgehört, Chats genauso wie Telefonate. Als Microsoft Skype kaufte wurde die Infrastruktur von p2p auf zentrale Server umgestellt, was damals schon zur Vermutung führte, dass Microsoft dies machte um Gespräche abhören zu können. Natürlich wurde das dementiert, nun ist bestätigt, dass es genau dazu führte.
Und das sind die Enthüllungen, die der USA in Snowdens Augen nicht schaden. Das schlimmste liege noch bei ihm. Mehr kommt bestimmt.
Bessere Piratenplakate
Dominic Veken hat recht: Die Wahlkampagne der Piraten ist wie eingeschlafene Füße. Die Plakate sind komplett harmlos und langweilig. Hier ein Beispiel:
Wtf. "Piraten wählen", ernsthaft?
Dabei gäbe es so schöne Slogans, so schöne Motive. Beispiele:
1. Prism: Bankpin
Ein Briefausschnitt ist zu sehen:
"Geehrte Frau Müller
Ihre vergessene Bank-Pin lautet 5689.
Herzlichst
Ihre NSA"
NSA-Logo als Briefkopf, Klarmachen zum ändern-Piratenlogo unten. Nie passte der Slogan besser. So wenig Text kriegt man auch problemlos lesbar groß genug unter, und das Motiv ist simpel genug, um es nächste Woche fertig zu haben.
2. Überwachung allgemein: Dusche mit Kamera
Überwachung als Eingriff in die Privatssphäre muss in Bilder gefasst werden. Ein Bild einer leeren Dusche mit installierter Überwachungskamera trifft es perfekt.
Und es wäre ein guter Anknüpfungspunkt für einen Videospot, da passt dann nämlich noch eine Frau rein, die sich ohne auf die Kamera zu achten duscht oder abtrocknet. Je nach Eskalationswunsch geht das mit null oder kompletter Nackheit. Oder gar mit einem Mann.
3. Lobbyismus: Aktenkoffer mit Dank
Basisdemokratie als Thema ist Lobbyistenkampf als Folgethema. Nichts einfacher als das - ein schwarzer Aktenkoffer, mit Klebezettel in der Mitte: "Danke für das Gesetz." Der Klebezettel blau-gelb unten, Hotellogo oben.
Hat Parallelen zu einem lokalen Piratenplakate von 2011.
Zu spät, wahrscheinlich, für diese Wahl und danach ist es höchstwahrscheinlich eh egal. Doch die Piraten müssten jetzt etwas tun, jetzt etwas bissiges bringen, da nichtmal Prism sie über die Prozenthürde zu heben scheint. Alles ist besser als die 0815-Formel grinsendes Politikergesicht mit langweiligem Slogan. Dass solche Plakate überhaupt passieren konnten ist eine Bankrotterklärung einer scheinbar toten Partei.
Alternativ die Gender-Spinner rausschmeißen, das dürfte durch die Mobilisierung der Zielgruppe eine neue Plakatkampagne ausreichend gut ersetzen.
Innenminister Friedrich verteidigt Prism
Unerträglich, wie er von einer angeblichen Gesetzesmäßigkeit und amerikanischen Warrants für deutsche Kommunikationsdaten (dann ist ja alles wieder gut) schwafelt (Direktlink, via).
Außerdem lügt er:
Ich habe mit dem Justizminister gesprochen und es geht nicht um ein flächendeckendes Scannen, sondern um eine gezielte Suche in einer begrenzten Zahl von Kommunikationsströmen, darum geht es.
Genau das ist nicht der Fall. Dass Geheimdienste bei Einzelpersonen mithören, das wussten wir schon vor Prism sicher und das war schon immer so. Vermeintliche Staatsfeinde und Terroristen werden abgehört, das nimmt eine Gesellschaft vll sogar bewusst hin. Aber Prism ist Massenscannen, Durchsuchen und Speichern der Kommunikation von allen, von relativ normalen Bürgern wie uns. Und das nicht nur in den USA, sondern sogar bevorzugt in Ländern wie Deutschland, Angriffszielen und Partnern dritter Klasse, deren Bürger als Nicht-Amerikaner nicht die (Menschen-)Rechte der amerikanischen Verfassung genießen.
Sein späterer Versuch, zwischen Daten und Metadaten zu unterscheiden, wobei erstere nicht gespeichert würden, ist erstens unglaubwürdig (bei verschlüsselten Daten stimmt das z.B. definitiv nicht, die werden fürs spätere Knacken gespeichert) und verharmlost zweitens diese Metadaten. Und unterschlägt drittens die Möglichkeit, unabhängig von der Speicherung einfach mal mitzuhören und mitzulesen. Amerikanische Position ist zwar tatsächlich, hier zu unterscheiden, das gilt aber nur für Inlandsüberwachung - die dadurch vermeintlich geschützten Verfassungsrechte gelten für Nicht-US-Bürger sowieso nicht.
Ein solches Verhalten eines deutschen Politikers, ein solches in den amerikanischen Arsch kriechen angesichts eines amerikanischen Angriffs, ist schlicht Landesverrat.
Event-Handler verschwinden durch innerHTML
Ich wollte eine einfache Liste mit Eingabefeldern bauen und per Javascript jeweils einen Entfernen-Button hinzufügen, und unten einen globalen Hinzufügen-Button, der weitere Eingabefelder produziert. Also im Grunde
<ol> <li class="guestInput">test1 x </li> <li class="guestInput">test2 x </li> <li class="guestInput">test3 x </li> + </ol>
mit Buttons.
Das war auch eigentlich kein Problem. Hier die Funktion zum Spawnen des Entfernen-Buttons:
function addRemoveButton(index) { var removeButton = document.createElement("button"); removeButton.type = "button"; removeButton.className = "remove icon-trash"; document.querySelectorAll(".guestInput")[index].appendChild(removeButton); removeButton.addEventListener("click", function() { this.parentNode.parentNode.removeChild(this.parentNode); }); }
Und so sah der JS-Code des Hinzufügen-Buttons aus:
var add = document.createElement("button"); add.type = "button"; add.className = "icon-plus"; add.addEventListener("click", function() { var http = new XMLHttpRequest(); http.onreadystatechange = function() { if (http.readyState == 4 && http.status == 200) { document.querySelector("#guestList").innerHTML += http.responseText; addRemoveButton(document.querySelectorAll(".guestInput").length-1); } } currentLength = document.querySelectorAll(".guestInput").length; http.open("GET","/guestInput?index="+ currentLength, true); http.send(); });
Per Ajax wird das HTML eines Eingabefelder geholt und dieses dann der Liste hinzugefügt.
Das Problem war, dass es so nicht funktioniert. Bei jedem Hinzufügen eines Eingabefeldes verschwanden alle alten Event-Handler.
Meine erste Lösung sah so aus:
function addRemoveButton(i) { var removeButton = document.createElement("button"); removeButton.type = "button"; removeButton.className = "remove icon-trash"; removeButton.dataset["index"] = i; document.querySelectorAll(".guestInput")[i].appendChild(removeButton); removeButtons = document.querySelectorAll(".remove"); for (var j = 0; j < removeButtons.length; j++) { removeButtons[j].addEventListener("click", function() { document.querySelectorAll(".guestInput")[this.dataset["index"]].parentNode.removeChild(document.querySelectorAll(".guestInput")[this.dataset["index"]]); }); } }
Da sind zwei Lösungsansätze vermischt:
- Falles es ein Scope-Problem sein sollte, werden die Index-Positionen im Dataset gespeichert und daraus gelesen.
- Als das nicht half kam die Brechstange: Jedes mal alle Event-Handler neu setzen
Absolut hässlich, aber ich kam einfach nicht darauf, wo das Problem liegt.
Dank einer Reihe von Fiddles kam ich nun darauf: Das Problem ist oben, beim Handler des Hinzufügen-Buttons:
document.querySelector("#guestList").innerHTML += http.responseText;
Durch die Manipulation per innerHTML werden die Event-Handler gelöscht. Die Lösung ist, regulär ein Element zu erstellen:
var newGuestInput = document.createElement("li"); newGuestInput.className = "guestInput"; newGuestInput.innerHTML = http.responseText; document.querySelector("#guestList").appendChild(newGuestInput);
Blöd ist, dass dafür Teile (der Klassenname und das li) statt per Template per Javascript gesetzt werden müssen. Aber trotzdem ist das Ergebnis wesentlich schöner als der Murks vorher.
Chrome: Audio-Event ended wird nicht gesendet
Ein Problem mit dem music-streamer war von Anfang an, dass es gar nicht so einfach war, nach Ende eines Liedes das nächste zu laden. Anfangs lud desöfteren ein gewähltes Lied einfach nicht und ich begann, last-modified Header passend zu setzen und mit dem Caching rumzuspielen, um das wenigstens nicht zu einem dauerhaften nicht ladenden - weil nur als Bruchstück gecachetem - Lied werden zu lassen. Außerdem reduzierte ich die Zahl parallel offener HTTP-Verbindungen zum Server. Trotzdem, manchmal klappte es einfach nicht.
Deswegen dachte ich mir wenig dabei, dass das Problem bestehen blieb. Manchmal lud einfach das nächste Lied nicht. Doch in den letzten Tagen hatte sich irgendwas verändert, ungefähr 50% der Lieder blieben stecken, und sie luden nicht nicht, sie wurden einfach nie ausgewählt - die Playlist blieb beim gerade gespielten Lied stehen. Da sich auf dem Server nichts geändert hatte, musste es am Browser liegen. Gestern konnte ich mir mal die Zeit nehmen und den Javascript-Code des Players vereinfachen und so ausschließen, dass es am Scheitern des Prebuffern des nächsten Liedes scheiterte, denn tatsächlich:
Chromium 28 sendet manchmal das ended-Event nicht, wenn das Lied zuende ist.
Sehr ärgerlich, weil im Code keine Beliebigkeit ist, das Event wird nicht nur manchmal gesetzt und ich sehe auch nichts, was wegen schlechtem Timing den Fehler manchmal auslösen könnte:
var player = document.createElement("audio"); player.id = "player"; player.setAttribute("controls", true); player.setAttribute("preload", "auto"); var source = document.createElement("source"); player.addEventListener('ended', function() { removeOldControls(); var newPlayer = createPlayer(index+1, songs); newPlayer.play(); insertOrReplace('#player', newPlayer); });
Das wurde mir jetzt zu blöd und ich untersuchte, ob ich das manuell fixen kann. Und ja, das geht, denn obwohl das ended-Event nicht gefeuert wird, die ended-Property wird trotzdem und scheinbar zuverlässig auf true gesetzt. Man kann also alle paar ms das Audio-Element fragen, ob es fertig ist, und wenn es eine Weile fertig ist ohne den nächsten Track auszuwählen, manuell das ended-Event abfeuern:
setInterval(function() { // occasionally, the end event is not triggered. Detect this and start the next track var player = document.querySelector('#player'); if (player.ended) { var event = document.createEvent("HTMLEvents"); event.initEvent("ended", true, true); player.dispatchEvent(event); } }, 200);
Seitdem blieb kein Lied mehr hängen.