Random Number Generator of Mono <= 3.12 is broken

Recently, I played around with the Random Number Generator (RNG) of the Mono Project 3.2.8. That version is a rather old one, but it’s the one shipped with Ubuntu 15.04. I needed some random numbers between 0 and 3:

Random rng = new Random();
var randomNumber = rng.Next(4); // you get 0,1,2 or 3

Actually, I was quite confused when I often I got the same sequence: 003311… sometimes it was also 110022… or 221133… or 332200… I double checked the way I initialized the RNG (you can barely do it wrong in .NET). Everything seemed okay. Self-doubts raised.

I created a new C# project to test this snippet it without other stuff around. Accidentally, I wrote this:

Random rng = new Random();
var randomNumber = rng.Next(3); // you get 0,1 or 2

And it worked. That was awkward. When I found the difference between the two snippets and changed the 3 to 4 again, it did not work again. That was even more awkward. I tested it with different upper limits, and most of them showed no strange effect. But some did: 2, 4, 8, 16, 32, 64, …

Okay that’s simple. Working hypothesis: use 2x as an upper limit and the RNG of Mono will rather be a Deterministic Number Generator than a Random Number Generator.

I wrote a small program which uses the RNG with different upper limits:

Random Numbers between 0 and (2-1)
001111111101100010010001010011
001111111101100010010001010011
001111111101100010010001010011
001111111101100010010001010011
110000000010011101101110101100
110000000010011101101110101100
110000000010011101101110101100
110000000010011101101110101100
110000000010011101101110101100
110000000010011101101110101100
There are 10 duplicates

Random Numbers between 0 and (3-1)
000012221000222111100200111111
002110221011201010101002210101
002120112122221110121201221122
010212222001202202120112122100
011100201221022100222110120012
012022010120000001211111022021
020110010111100020000121002221
021002110100121111002201202222
021002222022002221212022201000
022222222012120022212222102201
There are 0 duplicates

Random Numbers between 0 and (4-1)
003311313103322012030201010231
003311313103322012030201010231
110022020210033123101312121302
110022020210033123101312121302
221133131321100230212023232013
221133131321100230212023232013
221133131321100230212023232013
221133131321100230212023232013
332200202032211301323130303120
332200202032211301323130303120
There are 10 duplicates

Random Numbers between 0 and (5-1)
003102433303224320344124413244 
014002324010344001320033020132 
043243041241110034214310311202 
123102031104130223404020432042
144411314322324300000243000322
213020412123234203214144024130
303334443143224333420213212213
333430002031100042404304100321
413344002434130240034000230011
423243443040204021114414332404
There are 0 duplicates

Random Numbers between 0 and (6-1)
001151135521522414212403214033
003131555343524210030205054051
005313511105104012254401410413
041555513105100450212045434253
045111335343302054454043034235
310404240454033101343114125340
334024002052235305305330525322
350000402230453125123550501500
352044220054411521101552305124
354424444410413323525554145142
There are 0 duplicates

Random Numbers between 0 and (7-1)
033214526623606150556321512624
063341661552263666132455144332
140462111233332463413164456031
144456216033564651131621544310
205055051021666061606143460510
245621312432342225323012531145
352106204042035531250155442216
356163306202230353205312533565
450035402641045620130003124323
521500436411203455042330526446
There are 0 duplicates

Random Numbers between 0 and (8-1)
043755717107726016030205054635
114462060614077523101712125342
265177131321140230252427276057
265177131321140230252427276057
407311353543362452474641410271
407311353543362452474641410271
550026424250433167545356561706
621533575765504674616063632413
621533575765504674616063632413
772240646472655301767570703120
There are 6 duplicates

As you can see, everything works fine except for 2x as an upper limit. (On 8, there are only 6 duplicates. But this is because I only generated 10 sequences. With 30 sequences, there should probably be 30 duplicates.)

I ran this again for only the 2x upper limits (I removed the output of the sequences because that would have been a little bit too verbose):

Random Numbers between 0 and (2-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (4-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (8-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (16-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (32-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (64-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (128-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (256-1) 
There are 2000 duplicates 
 
Random Numbers between 0 and (512-1) 
There are 1993 duplicates 
 
Random Numbers between 0 and (1024-1) 
There are 1822 duplicates

Obviously, something is wrong with the 2x upper limits.

Mono introduced this RNG (JKISS) in version 3.2.7 and it remained there till it was replaced by Microsoft’s .NET Core implementation in Mono 4.0In 3.2.7, this RNG was introduced because „JKISS [..] is faster and has a longer period“. The change log references „Good Practice in (Pseudo) Random Number Generation for Bioinformatics Applications„.

Fun fact: Before version 3.2.7, Mono used the same RNG as Microsoft does. At least they seem quite similar. They are the RNG of Donald Knuth, described in Numerical Recipes in C, Second Edition (1992) p.283. Another fun fact: In Microsoft’s implementation, they use inextp=21 instead of inextp=31. Which in sequence created another bug. Unfortunately, they can’t simply fix it because some applications rely on this oddly initialized RNG. (As Mono is now also using this RNG, they’re buggy again – but at least compatible!)

Unfortunately, I’m no mathemagician and I have barely knowledge about crypto stuff. So I can’t really tell why there is this problem. As far as I figured out, JKISS generates random numbers, but if you apply a modulo operation, the resulting number sequence is always the same:

415579394 % 2 = 0
1247788766 % 2 = 0
1576907989 % 2 = 1
4120330265 % 2 = 1
373421407 % 2 = 1

2957693744 % 2 = 0
4000395092 % 2 = 0
565214835 % 2 = 1
3955692095 % 2 = 1
3013702125 % 2 = 1

586749482 % 2 = 0
2115627366 % 2 = 0
413595965 % 2 = 1
1496721121 % 2 = 1
2720998663 % 2 = 1

4215805220 % 2 = 0
230859640 % 2 = 0
261977095 % 2 = 1
3332717443 % 2 = 1
2428295201 % 2 = 1

235365793 % 2 = 1
3583443073 % 2 = 1
186167660 % 2 = 0
4250715604 % 2 = 0
2281943470 % 2 = 0

864421531 % 2 = 1
1698675347 % 2 = 1
34548790 % 2 = 0
1791744630 % 2 = 0
1989240008 % 2 = 0

So it is always 00111… (starting with even number) or 11000… (starting with odd number).

Further reading on why this may fail: http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx

Btw: Here’s the C# solution I used to test this: MonoBrokenRNG.tar

Varoufakis-Fake-Fake

Ich muss ja zugeben, dass ich so ein bisschen in Jan Böhmermann und das Team des NEO Magazins verliebt bin.

Besonders schön finde ich es, wenn Moderatoren den Mumm haben, ihre eigenen Zuschauer zu verarschen zur Reflexion zu bringen:

Am Sonntag war Yanis Varoufakis, Minister of Awesome, bei Jauch zugeschaltet. Dort wurde er auf den mehr oder weniger aus dem Zusammenhang gerissenen Stinkefinger angesprochen, den er beim Subversive Festival 2013 gezeigt hat. Varoufakis hat knallhart klargestellt, dass das Video ein Fake ist.

Das ist dann wohl das, was man als Steilvorlage für Satiriker bezeichnet. Im Weiteren folgt also meine persönliche Verschwörungstheorie :)

Am Mittwoch Abend hat das NEO Magazin nämlich folgendes Video online gestellt: Hashtag der Woche: #varoufake. Darin stellen Sie klar, dass das Mittelfinger-Video von ihnen ist und es alle Welt fälschlicherweise als Original ansieht.

Das Team des NEO Magazins hat sich dazu das originale Video des Subversive Festivals 2013 geschnappt und genau angesehen:
https://www.youtube.com/watch?v=MEUWxNifJJ8&t=2407

Was zum einen auffällt, sind diese roten Frames zwischendurch. Kann bei so einer Live-Aufzeichnung mit Amateur-Equipment vorkommen. Im Video des NEO Magazins wurden ebenfalls rote Frames eingebaut. Cleverer Schachzug: Man könnte nun vermuten, dass das Varoufakis-Video ebenfalls vom NEO-Magazin überarbeitet wurde und deswegen in beiden Videos die Frames auftauchen (sei es nun um ein Hinweis zu setzen, dass man es wirklich war; oder so zu tun, als ob die eigene Videosoftware irgendeinen Bug hätte. Beides im Grunde irgendwie absurd).

Das Varoufakis-Video wurde erst am 12. Februar 2015 auf YouTube hochgeladen veröffentlicht. Immerhin fast 2 Jahre nach der Konferenz. Ob das nun Zufall ist oder das NEO Magazin vielleicht tatsächlich Kontakt zu den Betreibern des Kanals hat – keine Ahnung. Aber es spielt dem Team des NEO Magazins natürlich in die Hände. Es ist ein schönes Argument dafür, dass man das Video erst kürzlich gefälscht und hochgeladen hat. [Update: Wenn man auf dem YouTube-Video auf More→Statistics klickt, sieht man allerdings „TIME WATCHED: 344 days“. Nach einer Diskussion im Google Productforum ist dies ein bekanntes Verhalten, wenn man ein Video zuvor nicht öffentlich gelistet hatte. (Danke an Ein_Schelm.)]

Für eine Analyse am interessantesten und stichhaltigsten sind aber ein paar Frames um ca. 2:15 aus dem NEO-Magazin-Video. Dort ist das scheinbar echte Video (d.h. ohne Stinkefinger) in voller Auflösung zu sehen. Perfekt um es sich genauer anzuschauen:

Varoufakis-Fake-Fake

Das Video habe ich mal noch auf 15% verlangsamt und zum selbst-anschauen auf YouTube geladen: https://www.youtube.com/watch?v=Yg7anGkUi6Q

Im 1. Frame sehen wir, dass Varoufakis das Kabel des Mikrofons ganz typisch einmal zu einer Schlaufe geschlagen hat. Im 2. Frame geht das Kabel ganz simpel nach unten. Diese beiden Frames dienen als Referenz für die nachfolgenden. Im 3. Frame sind nämlich zwei Kabel zu sehen. Im 4. und 5. Frame sind bei der Schlaufe zwei Kabel zu sehen. Im 6. Frame dann nur noch eines. [Edit: Sorry, das bei Frame 4, 5 und 6 ist zu ungenau und wahrscheinlich einfach nur die Manschette.] Schade eigentlich – da hätte man im Grunde noch einmal genauer hinschauen und retuschieren können. :-( Allerdings stand das Team auch unter gewissem Zeitdruck (oder sie wollten es nicht übertreiben ;-)).

Ich hoffe dennoch, dass dieser Fake-Fake große Wellen über das NEO Magazin hinaus schlägt. Die eigenen Zuschauer haben Böhmermann und sein Team immerhin schon mal veräppelt – ich bin gespannt ob, wann und wie sie das auflösen. Richtig witzig wäre natürlich, wenn der „Fake“ breiter von den Medien rezipiert wird und dann einmal so richtig alle verwirrt. Wie es auch kommt: Das war sehr großartig – und sei es nur, um die eigenen Zuschauer vorzuführen. Danke, Jan Böhmermann, danke NEO Magazin-Team. Bitte noch mehr Irritation!

copy random files to another directory

Sometimes (probably not that often), you want to copy a sample of files to another directory. For example, copy random mp3s of your collection to a flash drive for your car.

find /directoryWithMyFiles -print0 | shuf -z | xargs -0 cp -t /newDirectoryWithASampleOfFiles/

you could add -n100 to shuf to strip the sample down to 100 items. Otherwise, it will just copy your files as long as there is space left on the device containing the destination directory.

btw: works fine with spaces in file names or german umlauts.

Raspberry Pi und DCF77 Empfänger von Conrad

Gerade habe ich einen Raspberry Pi zur Funkuhr aufgerüstet. Das Funksignal kommt vom DCF77 – das ist der Sender, den auch eure normalen Funkuhren benutzen.

Conrad DCF77 Platine

Als erstes besorgt ihr euch die DCF77 Platine von Conrad: http://www.conrad.de/ce/de/product/641138/Conrad-DCF-Empfaengerplatine

Verkabelung

Sobald ihr die habt, beschriftet am besten gleich die Kontakte mit ihren Nummern:

  • 1: Masse / GND
  • 2: Betriebsspannung / VCC
  • 3: DCF Ausgang, normal
  • 4: DCF Ausgang, invertiert

DCF77 Platine Beschriftung

Kontakt 3 werden wir überhaupt nicht benutzen.

Zwischen Kontakt 2 und Kontakt 4 klemmt ihr einen Widerstand. Ich habe einen mit circa 6 kOhm benutzt.

Aus den Kontakten 1, 2 und 4 legt ihr jetzt jeweils ein Kabel heraus. Das Ende der Leitung ist am besten eine Steckverbindung, die man später einfach auf einen Pin draufstecken kann. Tut euch selber einen Gefallen, und verwendet (im Unterschied zu mir) drei verschiedenfarbige Kabel.

Ausrichtung

Bei der Platine ist eine Antenne dabei. Das ist dieses fette graue Ding aus Ferrit. Damit die Antenne den besten Empfang bekommt, richtet ihr sie „gegensätzlich“ zum Sender aus. Der Sender steht bei Frankfurt am Main (konkreter: Mainflingen).

Schaut am einfachsten bei Google Maps nach, wo ihr seid und wo Mainflingen ist: https://www.google.de/maps/place/Mainflingen,+Mainhausen/@50.3750485,9.3278463,7z/data=!4m2!3m1!1s0x47bd3f059ce2631b:0xa224352a99a4560

Schaut dann grob, was die Himmelsrichtung ist (von mir aus liegt Mainflingen in Richtung Nord-Nord-Ost). Nehmt dann einfach euer Smartphone zur Hand, schaut auf die Compass App und sucht wo die Himmelsrichtung ist. Wenn ihr die habt, dann muss die Antenne einfach 90° dazu gedreht werden. Außerdem sollte die Antenne einfach horizontal liegen und nicht etwa stehen. Achtet zudem darauf, dass die Antenne ausreichend weit von technischem Gerät entfernt ist. Ganz schlecht ist beispielsweise, die Antenne auf den Raspberry Pi zu legen oder in ein gemeinsames Gehäuse zu verbauen. (Die Chips erzeugen hochfrequente Wellen, die dann direkt wieder in eure Antenne gehen und das Signal komplett unbrauchbar machen.)

Raspberry Pi bzw. NTPd

Ich gehe mal davon aus, dass ihr den RPi schon eingerichtet habt. In meinem Fall habe ich die Raspbian Distribution verwendet. Bei einer anderen funktionieren die Dinge vielleicht etwas anders.

Verkabeln

Die Kabel die von der Platine kommen müssen natürlich noch an den RPi gesteckt werden. Eine Übersicht der Pins im Allgemeinen gibt es hier:

Raspberry Pi Pins und Belegung

(Die Grafik ist von http://developer-blog.net/hardware/raspberry-pi-gpio-schnittstelle-teil-1/, dem ewiger Dank und Ehre gebührt.)

Die Pins werden nun wie folgt verbunden (links die DCF77 Platine mit den Bezeichnern von oben, rechts der RPi mit den Bezeichnern der Grafik):

  • 1 (GND) → 9 („Ground“)
  • 2 (VCC) → 1 („3V3“)
  • 3 bleibt leer
  • 4 (DCF) → 10 (GPIO15 RXD)

DCF77 Platine

Serielle Konsole frei machen

Die Signale kommen später auf der seriellen Konsole an. Da das Linux standardmäßig diese Konsole für etwas anderes verwendet, müssen wir die erst noch frei machen. Dazu bearbeiten wir zuerst die Datei /boot/cmdline.txt. Standardmäßig stehen dort einige Parameter mit ttyAMA0 drin. Diese entfernen wir. Danach sah die Datei bei mir so aus:

wc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Die nächste Datei ist /etc/inittab. Dort kommentieren wir ebenfalls die Zeile zu ttyAMA0 aus:

#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

NTP einrichten

NTP beim if-up verhindern

Standardmäßig wird die Zeit von einem NTP Server geholt, wenn Raspbian eine Netzwerkverbindung bekommt. Das können wir in /etc/network/if-up.d/ntpdate abstellen. Da kann man als zweite Zeile einfach folgendes einfügen:

exit 0

Man kann die Datei stattdessen aber vermutlich auch einfach löschen.

Symlink setzen

Die Daten vom DCF77 Empfänger kommen über /dev/ttyAMA0 rein. Der ntpd wird die Daten aber auf /dev/refclock-0 erwarten. Also legen wir einfach einen Symlink. Da /dev ein tmpfs ist, muss der Link bei jedem Start neu erstellt werden. Das können wir einfach in /etc/init.d/ntp machen:

if [ ! -L /dev/refclock-0 ]; then
        ln -s /dev/ttyAMA0 /dev/refclock-0
fi

## diese vorhandenen Zeilen auskommentieren
#if [ -e /var/lib/ntp/ntp.conf.dhcp ]; then
#       NTPD_OPTS="$NTPD_OPTS -c /var/lib/ntp/ntp.conf.dhcp"
#fi

Zusätzlich haben wir damit noch ntpd gesagt, dass er sich nicht weiter um andere NTP-Server kümmern soll, über die wir evtl. von unserem Router informiert wurden.

NTPd einrichten

Die /etc/ntp.conf sollte so aussehen:

driftfile /var/lib/ntp/ntp.drift

# Enable this if you want statistics to be logged.
logfile /var/log/ntpd
logconfig =all
statsdir /var/log/ntpstats/

statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1

# nicht zwingend notwendig, nur für spätere Berechnung der fudgetime
server ptbtime1.ptb.de noselect
server ptbtime2.ptb.de noselect
server ptbtime3.ptb.de noselect

# der eigentliche Zeit"server", d.h. unser DCF77-Empfänger
server 127.127.8.0 mode 5

# diese Zeile beachten wir erst später, und dient zur Korrektur der Signallaufzeit
fudge 127.127.8.0 time1 YOUR_CALCULATION

Besonders wichtig ist die letzte Zeile. Diese etwas merkwürdige IP Adresse weist den ntpd an, den DCF77 Empfänger zu benutzen. Was man dabei wirklich wissen sollte, ist dass die 0 bedeutet, dass /dev/refclock-0 verwendet werden soll. Die 8 und das mode 5 sind auch wichtig, aber für’s Verständnis bzw. nachbauen egal.

Logging und Permissions

Dann gehen wir noch in /var/log und legen eine Datei ntpd an:

sudo touch ntpd && sudo chown ntp:ntp ntpd

Da der ntpd unter dem User „ntp“ läuft, muss dieser noch Zugriff auf die ttyAMA0 bzw refclock-0 bekommen:

sudo adduser ntp tty ; sudo adduser ntp dialup

(Meiner Meinung muss es die Gruppe dialup sein, aber einige Leute meinen, es sei tty. Daran soll es aber nicht scheitern: deshalb einfach beide.)

Logging Beispiele

Nachfolgend einige Meldungen aus dem ntpd-Log, und was sie bedeuten:

# vom Signal sind nur 7 bits angekommen; danach war die Verbindung gestört
31 Jul 00:07:00 ntpd[2533]: parse: convert_rawdcf: INCOMPLETE DATA - time code only has 7 bits

# alle Bits sind angekommen, aber der Paritäts-Check ist fehlgeschlagen
30 Jul 23:35:00 ntpd[2396]: parse: convert_rawdcf: parity check FAILED for "#-######-#--#---A--LS-2-81--P1---12p---8121-412----2-8---8"

# die Uhr hat sich erfolgreich synchronisiert und ntpd stellt seine Dienste im Netz bereit
31 Jul 00:08:00 ntpd[2533]: 0.0.0.0 c215 05 clock_sync

Fertig

Jetzt noch neustarten, und das sollte es dann auch gewesen sein.

Falls es nicht funktioniert, ist das natürlich schade. Unter /var/log/ntpd gibt es evtl. weitere Anhaltspunkte. Ebenso gibt ein „ntpq -c as -c cv -c rv“ mitunter sinnvolle Informationen.

Sollte etwas grundlegend nicht funktionieren, ist man ohne Elektrotechnik-Kenntnisse und -Bastelkiste vermutlich aufgeworfen.

Software-seitig gibt es dieses sehr hilfreiche Tool: https://github.com/rene0/dcf77pi Damit kann man die Daten des Empfängers auslesen. Die DCF-Verbindung sollte dazu auf Pin 11 (GPIO17) gelegt werden. Zusätzlich muss man eventuell in der Config (wenn ich mich recht erinnere) „activehigh = 0“ setzen

Fudgetime korrigieren

Wenn man NTP übers Internet benutzt, dann kann er die Latenz recht gut messen und herausrechnen. Bei Funk geht das aber nicht, da er nicht weß wie lange das Signal denn nun zum Verarbeiten gebraucht hat. Deswegen kann man einmal am Anfang einen Internet-NTP Server als Referenz nehmen, um das zu berechnen.

Kopiert euch dafür dieses schnell von mir zusammengefrickelte Skript und führt es aus:

echo "This script will calculate the mean offset if you provided some noselect ntp-servers in your ntp.conf"

echo "If you did not provide any noselect ntp servers, this script will fail. It will also fail if those servers are not reachable."

echo
echo "Your current fudge time is:"
ntpq -c cv | grep fudgetime1 | cut -d" " -f 5

echo
echo "The mean offset (compared to the 'noselect' ntp-servers in your ntp.conf) is:"
cat /var/log/ntpstats/peerstats | grep -v 127.127.8 | cut -d" " -f 5 | awk '{a+=$1} END{print a/NR}'

echo
echo "Add up those values, divide them by 1000, and add this line to your ntp.conf:"
echo "fudge 127.127.8.0 time1 YOUR_CALCULATION"

In der Ausgabe sollte so etwas stehen wie, dass die aktuelle Fudgetime (fest einprogrammiert) 292ms ist, und der gemessene Offste ist zusätzlich vermutlich circa 640ms. Das rechnet ihr zusammen, dividert es durch 1000 und tragt dann also bspw. das hier in die ntp.conf ein:

fudge 127.127.8.0 time1 0.932

automatischer Restart bei Panic Stops

Manchmal, wenn auch tendentiell selten, kommt es vor, dass der Sender eine falsche Uhrzeit empfängt. Meist wird das durch Parity-Bits verhindert – aber manchmal schlägt das fehl. Wenn die Zeit dann mehr als 1000 Sekunden von der aktuellen abweicht, dann beendet sich ntpd. Im Falle von NTP mag das sinnvoll sein, aber bei einer DCF77-Funkuhr ist das eher kontraproduktiv.

Deswegen richten wir ein Monitoring ein, das einfach ntpd neustartet sobald er sich beendet hat. Dazu installieren wir zuerst das Paket „monit“ und richten dann die Datei /etc/monit/conf.d/ntpd ein:

check process ntpd with pidfile /var/run/ntpd.pid
group ntpd
start program = "/etc/init.d/ntp start"
stop program = "/etc/init.d/ntp stop"

GPS based Geolocation of pictures in digiKam

Recently, I got a new DSLR. It’s a Canon 1200D/Rebel T5 (basically the one you choose if you don’t know anything about photography). Of course I want the geolocation in my EXIF data.

Unfortunately, there is no GPS built in. You can probably buy a GPS module and stuff, but I don’t want to buy additional stuff for something rather unimportant. As I’ve got a smartphone, I can track my position anywhere I go.

There are at least two possibly ways to track you location with Android. The first one is accurate, uses GPS and is the smart one:

Google My Tracks

There is a nice App from Google called „My Tracks“. Ensure you’ve got GPS enabled, and then just press the record button when you start shooting and press end when you’re done. Choose your track from the list, go to the menu and tap on „export“. Save as GPX and then send it to your computer (e.g. „add to dropbox“ or something). Voilá, you’ve got a GPX file. Now, go to the digiKam section.

As this tool automatically syncs your tracks to Google Drive, you can also just go there and download them all. In this case, they are KML or KMZ-files. Therefore, you have to use a perl script to convert them from KML/KMZ to GPX. How to use this script is described in the next section.

KML are uncompressed files and KMZ are compressed. Therefore KMZ files have to be uncompressed first. This can easily be done with this command:

for i in *.kmz; do unzip -p "$i" > "$(basename "$i" .kmz)".kml; done

Google Location History

Of course, there is a catch: You have to remember to start the App. But usually, you catch your camera, start walking around and shooting pictures, and as soon as you come home you notice that you’ve got forgotten to record your track.

Luckily, Google knows everything about you and especially where you’ve been. Android records the WiFi networks your smartphone sees and uploads them to Google (at least if you allowed it). Go to Google’s Location History and select the day when you’ve been shooting. If you don’t even remember this one, just select to download the last 30 days. You will get a KML file which is pretty much useless, as most tools use GPX files.

Converting KML to GPX

There are many tools which can convert KML files to GPX. But most don’t seem to work, create an empty file or cripple up your timestamps. So go to GPS Visualizer and upload your KML file. Make sure to select GPX as output format and hit convert. Once the upload and conversation finished, you can download a GPX file. I would recommend using this nice perl script if you know what a command line is.

You can convert KML files easily by running this script on every KML file. (Make sure that you uncompressed KMZ files if there are any.)

perl kmlwpt2gpx.pl *.kml

Correlate your pictures in digiKam

This is the easy part: Select your pictures in digiKam. You may only want to tag pictures which have no geotag so far. Choose the „Table“ view and add a new column to the table. Add the „Geotagged“ column which will show you a yes/no column whether the picture has been tagged already. This makes sure you don’t overwrite accurate GPS-based locations with inaccurate WiFi-Location-based tags. Select all not-geotagged pictures. Click on Image → Geolocation → GPS Correlator and load your GPX file(s).

If you used a GPS tracker, you probably do not have to change anything. If you used Google Location History, then you have to tweak some settings. Adjust the maximum time gap to 600 secs (worked fine for me). Then choose „manual time zone“. And then you have to calculate.

Currently, I’m in GMT+2 (Germany and Daylight Saving Time). Google is located in California which is GMT-7. So the correct offset is GMT+9. If you used the perl script above, you don’t have to adjust the timezone.

Hit „correlate“, switch to Google Maps in the upper left view (click on the globe), and check if everything is okay. Then hit Apply and wait till digiKam finished tagging your pictures.

That’s it. Happy shooting & geotagging!

Akkus beim Laden zuschauen.

Nächste Woche startet mein Experiment. Ich werde dann 5 Tage lang von 08:00 bis 20:00 am KIT in einem Labor sein. Da werde ich jeden Tag 4-mal einer Gruppe von 5 Personen dabei zuschauen, wie sie Filme anschauen und Fragebögen ausfüllen.

Ja. Unter Forschung stellt man sich gemeinhin wohl etwas spektakuläreres vor. ;-)

Im Moment bereite ich das Experiment vor. Ich habe hier 5 Tablets und Bluetooth-Sensoren. Das wird im Experiment alles auf Akku laufen. Das heißt dann auch, dass der Akku nach Möglichkeit nicht mitten im Experiment schlapp macht.

Wirrwarr

Wie stellt man das sicher, dass das alles funktioniert? Nun. Ich sitze hier und schaue zwei Tablets und Sensoren dabei zu, wie sie sich aufladen und dokumentiere die Zeiten und Ladestände. Zwei anderen Tablets und Sensoren schaue ich dabei zu, wie sich sich während der Nutzung entladen.

Wie gesagt. Mitunter ziemlich wenig Knall und Peng in der Forschung. Bei allem, was langwierig und stupide wirken mag: Ich kann mir keine schönere Thesis vorstellen.

Liebesgrüße vom Congress. Für Zeitungsleser/Innen.

Hi liebe Leserin oder Leser, welche/r du gerade von deine/r Lieblingszeitung hier hergekommen bist!

Wahrscheinlich bist du wegen diesem CCC-Spam-HsKA-Dings hier. Deswegen stell ich hier noch mal übersichtlich alle relevanten Links zusammen:

  1. Hier im Blog gibt es Informationen zum technischen Ablauf und Hintergrund:
  2. ein mal für Nerds.
  3. und ein mal für normale Menschen.
  4. Tim Roes hat einen offenen Brief an die HsKA geschrieben.
  5. der ist auf funkenstrahlen.de zu finden; so wie die Infos zur Ausladung von Constanze Kurz

Viel Spaß!

Liebesgrüße vom Congress. Für Nicht-Techies.

Vor ein paar Tagen habe ich eine Anfrage einer Redakteurin von ka-news.de erhalten. Der Artikel ist mittlerweile veröffentlicht. Die Bitte war, noch einmal für Laien zu erklären, wie der Angriff auf den Mail-Server der HsKA ablief. Da die Mail eine beachtliche Länge erreicht hat, und ich in ihr noch mal einiges auf einem verständlicheren Niveau erläutert habe, möchte ich den Inhalt hier gerne noch einmal verwerten. Einige persönliche Details sind natürlich angepasst, und die privaten Teile der Kommunikation entfernt. Viel Spaß:

Ich werde versuchen, das Problem möglichst anschaulich für Außenstehende zu beschreiben. Falls ich zu sehr in Technikblabla abdrifte oder etwas zu unverständlich beschrieben habe, fragt gerne noch mal nach.

In der HsKA gibt es verschiedene Server-Systeme. Diese werden vom IZ („Informationszentrum“) betrieben (wo anders heißt das üblicherweise „Rechenzentrum“/RZ). Jede/r MitarbeiterIn und StudentIn hat dort einen Account. Mit dem können Daten zentral abgelegt werden, mit dem WLAN verbunden werden, E-Mails abgerufen werden und so weiter. Es gibt zwei Komponenten die für den Angriff genutzt wurden; und die man an und für sich eigentlich nicht unbedingt als klassische „Sicherheitslücke“ beschreiben würde. Aber sie haben das Potenzial, das man damit Schabernack treiben kann.

Diese beiden Komponenten sind zum einen der Unix-Server und zum anderen der Mail-Server.

Auf den Unix-Server kann man sich über eine Kommandozeile einloggen. Das sieht dann in etwa so aus: http://www.elated.com/res/Image/articles/management/unix/ssh-and-basic-commands/putty-logged-in.jpg
Das ist allerdings nichts besonderes. Früher war DAS quasi der Standard wenn man mit Computer gearbeitet hat. Die meistens von uns sind allerdings etwas zu jung, um das noch live miterlebt zu haben :) Bei Servern ist das allerdings immer noch vollkommen üblich.

Was kann man nun also machen, wenn man sich auf diesen Server der HsKA eingeloggt hat? Dort gibt es eine Datei, in der alle Nutzer stehen. Dort stehen zum einen die Benutzerkürzel (etwas wie „muli1045“) und zum anderen die Vor- und Nachnamen (also beispielsweise „Lieschen Müller“). Für Außenstehende hört sich das jetzt vielleicht etwas beunruhigend an. Aber im Grunde ist das wie damals im Telefonbuch: Es steht halt jeder mit seinem Namen und Adresse drin. Für Unix-Server ist das vollkommen üblich. Dort stehen im Fall der HsKA etwa 10600 Nutzer drin. Als solche Systeme konzipiert wurden, war das auch für den internen Betrieb ganz interessant: Man konnte einfach nachschauen, wie der Benutzername vom Kollegen ist, dem man eine Mail schicken wollte.

Das war Schritt 1 – denn die Benutzerkürzel sind der vordere Teil der E-Mail Adresse (muli1045@hs-karlsruhe.de).

Jetzt muss man nur noch die Mails versenden. Dazu benutzt man einen Mail-Server. Mit diesem Mailserver können sich Mail-Programme verbinden. Zum Beispiel „Thunderbird“ oder „Outlook“. Wenn man diese Programme einrichtet gibt man den Mail-Server an, den man zum Versenden nutzen möchte. Die meisten Mail-Server verlangen dabei, dass man sich dafür einloggt. Dann muss man seinen Benutzernamen und sein Passwort übermitteln. (Vielleicht geben Sie das Passwort auch jedes mal ein, wenn Sie eine Mail senden. Wenn nicht, dann hat Thunderbird das Passwort vermutlich für Sie gespeichert und macht das automatisch.) Bei der HsKA war dies nicht der Fall. Um genauer zu sein: Es war nur manchmal der Fall. Und zwar musste man ein Passwort eingeben, wenn man eine Mail von muli1045@hs-karlsruhe.de an mueller@example.org geschrieben hat. Wenn der Empfänger also außerhalb der HsKA war. (Um mal eine Analogie zu wählen: Wenn man Post nach draußen versenden will, dann verlangt die interne Poststelle den Dienstausweis) Wenn der Empfänger jedoch innerhalb war (also muli1045@hs-karlsruhe schickt eine Mail an hufe1064@hs-karlsruhe.de), dann musste kein Passwort eingegeben werden. (Analogie: Das war quasi Hauspost. Wenn intern Post versendet wird, dann glaubt der Postbote einfach, dass kein Quatsch gemacht wird und verzichtet auf den Dienstausweis.)

Was am 29. Dezember passiert ist, war dass dieser interne Versand genutzt wurde (alle Empfänger waren ja HsKA-MitarbeiterInnen/Studierende). Um in der Analogie zu bleiben wurde dem Postboten ein großer Stapel Briefe vorgelegt. Auf allen Briefen stand ein interner Absender und interner Empfänger. Der Postbote hat also einfach brav die Post an alle Nutzer ausgetragen.

Wie kommt jetzt der Chaos Computer Congress ins Spiel? In jeder Mail steht „versteckt“ eine „IP-Adresse“. Das ist eine Identifikationsnummer, die zu meiner Internetverbindung gehört. In Thunderbird werden Sie meine IP-Adresse auch sehen können. Wenn sie STRG+U drücken, können Sie mal nach „46.23.42.5“ suchen. Das ist meine aktuelle IP-Adresse. Für potenzielle Angreifer ist das ein Problem: In Deutschland gibt es die Vorratsdatenspeicherung und die Provider sind verpflichtet, diese Verbindungsdaten zu speichern. (Das ist ein eigener Themenkomplex, auf den ich nicht weiter eingehe.)[Notiz: Hier habe ich Bullshit erzählt. Die Vorratsdatenspeicherung wurde 2010 für verfassungswidrig erklärt. IP-Speicherungen sind bei der Telekom aber beispielsweise für kurze Zeit dennoch üblich.] Wenn der Angreifer von Zuhause aus mit seinem Telekom-Internet-Anschluss die Mails verschickt hätte, könnte er sich sicher sein, dass die Telekom sofort seine Daten rausrückt. (So war das beispielsweise bei dieser RedTube-Porno-Abmahnungs-Geschichte vor einigen Monaten.) Was macht der Angreifer also? Er nutzt eine IP-Adresse, die nicht auf ihn zurückverfolgbar ist. Dies ist beispielsweise beim 30. Chaos Computer Congress (30C3) der Fall gewesen. Da gibt es Internet für alle und die IP-Adressen gehören dem Chaos Computer Club (CCC). Der CCC widersetzt sich jedoch der Vorratsdatenspeicherung[Notiz: Da es diese nicht mehr gibt, müsste man eher sagen: Der CCC protokolliert halt nichts.]. Wenn dort jemand ins Internet geht wird nichts protokolliert (und schon gar nicht mit einer Person in Verbindung gebracht). Die HsKA hat wohl beim CCC angefragt, wer die IP genutzt hat. Der CCC hat vermutlich nur geantwortet „keine Ahnung“.

Vom 30C3 aus hatte der Angreifer also die Möglichkeit, einen guten Stapel Mails zu versenden.

Aber ich hatte doch vorher gesagt, dass man von intern nach intern kein Passwort angeben muss. Wie verhält sich das, wenn man beim 30C3 sitzt? Dem Mail-Server ist das egal. Auf der Mail kann dennoch ein interner Absender stehen. Ob man dem Postboten die Briefe übergibt während man in der Hochschule sitzt oder auf dem 30C3 – das interessiert ihn nicht.

Okay. Das kann man, wenn man möchte, als Sicherheitsproblem bezeichnen. Es wäre vielleicht etwas geschickter, wenn der Postbote bei der Hauspost auch nach dem Dienstausweis fragt. Das ist in der Regel üblich und wurde jetzt auch an der HsKA eingeführt. Wenn man nun Mails von intern nach intern schicken will, wird man nach seinem Passwort gefragt.

Jetzt kommen wir aber zu einem Teil, der über das Oberflächliche hinaus geht, und vielleicht Potenzial zur Beunruhigung hat: Für die meisten Nutzer hört sich das an, als könnten jetzt keine gefälschten Mails mehr ankommen. Aber eigentlich funktioniert das immer noch. Das ist nicht die Schuld unseres Rechenzentrums, sondern eine Schwäche des Mail-Protokolls.

Ich möchte die Analogie mit den Briefen fortführen. Stellen wir uns einen Brief mit Umschlag vor. Auf diesem Umschlag steht vorne „Lieschen Müller, ka-news-Straße 23“ und hinten steht „Diddi Debuglevel, ka-news-Straße 23“ (angenommen ich würde auch bei ka-news arbeiten). Das was auf dem Umschlag steht, hat die Hauspost benutzt um den Brief zuzustellen. Der Postbote hat das auf Ihren Schreibtisch gelegt und ist (hinkende Analogie) so nett, die Briefe gleich auszupacken. Sie kommen also morgens in die Redaktion und haben die geöffneten Briefe vor sich – Sie sehen also nie, was auf dem Umschlag stand. Auf dem Briefpapier steht jetzt also „Hi Lieschen! Ich habe dich gestern in der Kantine gesehen und war total verliebt. Liebe Grüße Johannes“. Nur hat Johannes (der süße neue Volontär von ka-news) diesen Brief nie geschrieben, sondern Diddi. Da steht allerdings nur auf dem Umschlag – und den haben Sie nie gesehen. Da hat es am Ende auch nichts gebracht, dass die Hauspost von Diddi den Dienstausweis beim Absenden verlangt hat.

Irgendwie doof. Aber es kommt noch blöder: Chris, ihr hoffentlich nicht existierender saufieser Ex, schreibt ebenfalls einen Brief an „Lieschen Müller, ka-news-Straße 23“. Er wirft den Brief in den Postkasten, der wird ausgetragen und landet wieder geöffnet auf ihrem Schreibtisch. Von wahren Absender wissen sie nichts. Was sie bisher nicht wussten: Der Postbote ist so nett und lässt den Briefumschlag ebenfalls auf dem Tisch liegen. Falls Sie also Verdacht schöpfen, können Sie sich den Briefumschlag anschauen. Und da steht dann der wahre Absender drauf. Naja zumindest vielleicht. Wir kennen es von Briefen: man kann als Absender jeden Quatsch draufschreiben. Chris hätte also genau so gut „Johannes Schlüter, Regenbogenstraße 12″ als Absender draufschreiben können.

Was ich mit dem zweiten Teil versucht habe klarzumachen: Mail (so wie Briefe) sind nicht vertrauenswürdig. Man kann sich im Grunde nie wirklich sicher sein, ob a) der Absender stimmt, b) der Inhalt unterwegs nicht von der NSA gelesen wurde, d) der Inhalt unterwegs nicht von jemand verändert wurde.

Das sind Probleme, die Konzeptions“fehler“ der Mail sind. (vermutlich hat man damals einfach nicht gedacht, dass das mal ernsthaft benutzt und entsprechend missbraucht wird.) Diese Probleme lassen sich durch gewisse Zusatzmethoden beheben. Man kann zum Beispiel seinen Brief verschlüsseln – und nur der Empfänger kann ihn wieder entschlüsseln und lesen. Und man kann eine Unterschrift unter seinen Brief setzen. Mit der Unterschrift kann man prüfen, ob der Absender wirklich derjenige ist, der er vorgibt zu sein. Allerdings ist es für normale Nutzer vergleichsweise schwierig, das zu überprüfen. Das ist nicht unmöglich, aber eben nicht sonderlich gängig und für normale Nutzer eher alles kontraintuitiv.

Okay… ich glaube, ich habe irgendwie alles halbwegs behandelt, was wichtig war. Zur Ausladung von Constanze Kurz… nun, das ist Politik. Den Artikel auf Golem.de kennen Sie vermutlich ebenso wie den Offenen Brief von Tim R. und den Blog-Artikel auf Funkenstrahlen.de.

Audio als FLAC aus Video extrahieren (VLC)

for i in *.MOV; do
  vlc -I dummy --no-sout-video --sout-audio  --no-sout-rtp-sap --no-sout-standard-sap --ttl=1 --sout-keep  --sout "#transcode{acodec=flac}:std{mux=raw,dst=$i.flac}" $i vlc://quit;
done

Liebesgrüße vom Congress

Die Mail

Heute gab es um 15:43 eine Ladung Liebesgrüße für alle Studierenden der Hochschule Karlsruhe. Die kamen per Mail an die Hochschuladresse an und waren wie folgt aufgebaut:

Betreff: Hi!

Hi <Empfänger-Vorname>,

ich hab dich letztens auf dem Campus gesehen und musste dich einfach ewig ansehen. Ich glaube du warst mit Kommilitonen auf dem Weg zur Mensa oder so. Ich muss seitdem immer und immer wieder an dich denken und könnte mir echt in den Hintern beißen, dass ich dich nicht direkt angesprochen habe!

Jetzt versuche ich seit 2 Wochen irgendeine Kontaktmöglichkeit zu finden und war echt froh, als mir <zufälliger Studi-Vorname> deine Emailadresse gab!

Ich würde dich gerne näher kennen lernen und würde mich freuen, wenn wir uns mal auf nen Kaffee oder Cocktails am Abend treffen könnten! Vielleicht lässt sich ja in Zukunft die Zeit auf dem Campus gemeinsam verbringen?

Ich hoffe ich habe dich mit meiner direkten Anschrift nicht zu sehr überrumpelt und würde mich sehr über eine Antwort freuen!

<Absender-Vorname>

Der Mail-Header

Okay. Auch wenn ich mich irgendwas zwischen geschmeichelt und verwirrt gefühlt habe, habe ich dann doch lieber die Mail-Header überprüft. (Den Absender habe ich mal durch mami0003 (Testuser „Micky Mouse“) und den Empfänger durch fufu0001 (vollkommen fiktiv) ersetzt.)

Return-Path: <mami0003@hs-karlsruhe.de>
[... unwesentliches gelöscht ...]
Received: from schinderhannes.visitor.congress.ccc.de ([151.217.107.113] helo=[127.0.0.1])
by smtp.hs-karlsruhe.de with esmtp (Exim 4.80.1)
(envelope-from <mami0003@hs-karlsruhe.de>)
id 1VxHa6-009Kd2-MV
for fufu0001@hs-karlsruhe.de; Sun, 29 Dec 2013 15:43:06 +0100
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
From: Micky Mouse <mami0003@hs-karlsruhe.de>
To: fufu0001@hs-karlsruhe.de
Date: Sun, 29 Dec 2013 14:43:06 -0000
User-Agent: SimpleMail Python/2.7.3
(http://www.python-forum.de/post-18144.html)
Subject: Hi!
X-HELO_host_verified: No (RFC 2821 violation detected)
X-HsKA-Point: HELO host verification failed (RFC 2821 violation detected).
X-HsKA-Point: host does not belong to domain or MX of sender address
X-HsKA-Points: pp

Hier sind zwei Sachen verdächtig:

1.

User-Agent: SimpleMail Python/2.7.3

2.

Received: from schinderhannes.visitor.congress.ccc.de ([151.217.107.113] helo=[127.0.0.1])

Ein Nerd wird hier denken „lol.“ für normale Menschen erkläre ich es kurz:

Der User-Agent bezeichnet das Programm, mit dem die Mail verschickt wurde. SimpleMail ist eine Programmbibliothek für die Programmiersprache Python. Dass das jemand ernsthaft als normales Mailprogramm einsetzt darf bezweifelt werden. Es ist daher eher ein Indiz für ein Skript zum automatisierten Versenden von Mails.

Die zweite Zeile zeigt an, wer die Mail abgesendet hat. Dies war in diesem Fall der Host „schinderhannes.visitor.congress.ccc.de“. Das deutet stark auf einen Besucher des aktuell stattfindenden 30C3 hin.

Der Chaos Communication Congress

Liebesgrüße vom Congress? Unwahrscheinlich ;-)

Vom 27.12 bis zum 30.12 findet jährlich der Chaos Communication Congress statt. Das ist die weltgröße LAN-Party ein großes Hacker-Treffen welches vom CCC (Chaos Computer Club) in Hamburg abgehalten wird. Dort trifft sich die jährlich die internationale Hackerszene für Vorträge, Networking und zum Spaß haben.

Von dort aus werden auch gerne Sicherheitslücken aufgezeigt (eine Liste der aktuellen Hacks des 30C3 edit: mittlerweile ist das Original nicht mehr vorhanden). Weil das „zwischen den Jahren“ und ohnehin eher anarchistisch ist, können die Hacker schwer bis gar nicht verfolgt werden. (Auch wenn es dort angeblich ein Sorgentelefon gibt, an das sich Externe wenden können wenn sie Ziel eines Angriffs geworden sind.)

Der SMTP-Server

Wie konnten diese Mails nun abgeschickt werden? Leider ziemlich leicht. (Das liegt allerdings nur teilweise in der Infrastruktur der HsKA begründet. Mail ist im Allgemeinen nicht sonderlich sicher.) Der der SMTP-Server der Hochschule Karlsruhe hat ein paar Eigenheiten, die hier ausgenutzt wurden:

  • Der Server ist außerhalb des HS-Netzwerkes erreichbar (das ist vollkommen normal und notwendig)
  • Mails an …@hs-karlsruhe.de können ohne Login gesendet werden. Das heißt er setzt kein SMTP-Auth voraus. (Mails an alle anderen Adressen benötigen eine Verbindung über VPN.)
  • Als Absender muss ein lokal existierender Nutzer angegeben werden (hier „mami0003“).

Kurz: Jeder kann von überall aus seine E-Mails damit versenden, solange der der Absender (hier: „mami0003“) existiert.

Nachfolgend ein Beispiel, wie man selber „Hacker“ spielen kann. (Windows-Nutzer ersetzen netcat durch telnet). Das ist kein geheimes Hacker-Wissen, sondern einfach nur das, was auch euer E-Mail Client macht wenn ihr eine Mail verschickt.

Ihr könnt das selber ausprobieren, solltet aber unbedingt darauf achten, dass ihr die Mails nur an euch selber sendet und (anders als der Hacker) keine anderen Studis damit nervt. Außerdem steht eure IP in der Mail, mit der ihr in der Regel rückverfolgbar seid.

$ netcat smtp.hs-karlsruhe.de 25
220 smtp.hs-karlsruhe.de ESMTP HGS 5.0 Sun, 29 Dec 2013 18:59:14 +0100
HELO foobar.example.net
250 smtp.hs-karlsruhe.de Hello
MAIL FROM:<mami0003@hs-karlsruhe.de>
250 OK
RCPT TO:<fufu0001@hs-karlsruhe.de>
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
From: <sender@example.org>
To: <receiver@example.com>
Subject: Testmail
Date: Thu, 26 Oct 2006 13:10:50 +0200
Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua.
.
250 OK id=1VxKgp-009DB4-38
QUIT
221 smtp.hs-karlsruhe.de closing connection

Die genauen Details und deutlich übersichtlicher kann man das in der Wikipedia nachlesen: SMTP Protokoll

Prinzipiell könnte man auch ein neues Thunderbird-Profil aufsetzen und damit Mails versenden. Aber dann ist der Lerneffekt doch eher gering.

(Info für alle WI-Studis an der HsKA: Im Modul „Kommunikationssysteme“ werdet ihr das noch einmal brauchen, da ihr dort einen E-Mail Client programmieren werdet.)

Die Personendaten

Aber wie kam man an die Mail-Adressen und die Namen? Nun, die liegen wie bei jedem guten Unix einfach auf dem Server herum (im folgenden Beispiel habe ich zusätzlich nach dem Testuser „Micky Maus“ gefiltert).

Dazu loggt man sich auf dem Server der Hochschule ein und sieht sich die datei /etc/passwd an. Auch das hat mit „hacken“ nichts zu tun. Der Server ist für alle Studis frei zugänglich – weitere Infos dazu finden sich in der Dokumentation im ILIAS („Wie kann ich mit Putty eine SSH-Sitzung starten?“).

$ ssh fufu0001@login.hs-karlsruhe.de
fufu0001@login.hs-karlsruhe.de's password:
****************************************************************************
* *
* H O C H S C H U L E K A R L S R U H E *
* T E C H N I K U N D W I R T S C H A F T *
* *
* ( I n f o r m a t i o n s z e n t r u m ) *
* *
* *
* I Z - B e n u t z e r b e r a t u n g *
* Montag bis Freitag 8:00-14:00 Uhr Telefon: 0721 / 925 - 2305 *
* *
* Aktuelle Ankuendigungen und Betriebshinweise/Wartungstermine *
* siehe unter http://www.iz.hs-karlsruhe.de/ *
* *
* *
* Welcome to AIX on IBM System p *
* *
****************************************************************************
$ cat /etc/passwd | grep Micky Maus
mami0003:!:132213:100000:Micky Maus:/home/A3_D1_L103/mami0003/home:/usr/bin/ksh
mami1029:!:250541:200000:Micky Maus:/home/A3_D1_L103/mami1029/home:/usr/bin/ksh
$

Es gibt auf dem Server also zwei Nutzer (mami0003 und mami1029) mit dem Namen Micky Maus. Wäre der Filter nicht gesetzt, würde noch alle weiteren User mit Vor- und Nachname aufgelistet. Das ist also prinzipiell eine Quelle für die Namen und E-Mail-Adressen.

Eine weitere Möglichkeit, die hier vielleicht genutzt wurde, ist der LDAP-Server welcher zum Active Directory der Hochschule gehört. Dies ist ein Verzeichnisdienst, welcher dazu genutzt wird um solche Daten strukturiert abzulegen und abzufragen.

Et voilá

Kombiniert man die (prinzipielle) Unsicherheit von Mail und die Nutzerliste, so kann man mit relativ einfachen Mitteln die randomisierte Partnervermittlung betreiben, wie es der Hacker tat. (Da die E-Mail-Adressen auch wirklich existieren, führt dies dazu, dass sich die Turteltäubchen gegenseitig antworten können. Wie romantisch! ;-))

technische Implikationen für Nutzer

Was bedeutet das für mich als User im Umgang mit „normalen“ Mails (d.h. ohne Verschlüsselung und Signatur)?

  1. Die eingetragene AbsenderIn einer Mail ist willkürlich. Man kann sich niemals sicher sein, dass die Mail wirklich von ihr stammt.
  2. Die eingetragene EmpfängerIn ist im Prinzip auch willkürlich. Im Prinzip könnt ihr auch eine Mail erhalten, die scheinbar an angela.merkel {at} cdu.de gesendet wurde, aber bei euch ankam.
  3. Der Inhalt kann verfälscht sein. Man weiß nie, ob unterwegs etwas verändert wurde.
  4. Der Inhalt kann entsprechend auch unterwegs mitgelesen werden.

Eine Antwort auf alle Fragen heißt im Grunde Verschlüsselung und Signierung. Dies ist zum Beispiel über PGP bzw. GPG mittels im Public/Private-Key Verfahren möglich. (Sicherheitskonzepte für Mail in der deutschen Wikipedia)

Ein weiterer Punkt, der damit allerdings nicht verhindert werden kann, ist die Ausspähung der Metadaten („Bewegungsdaten“). Dies sind beispielsweise Empfänger, Absender, Datum und auch der Betreff. Wer dies schützen will, der muss schlichtweg ein anderes Protokoll nutzen oder das ganze über beispielsweise Tor abwickeln (solange das noch nicht von der NSA unterwandert ist).

technische Implikationen für Admins

Die Protokolle rund um „Mail“ sind an sich ein ziemlicher Flickenteppich, an dem immer wieder neue Sicherheitsflicken angebracht werden um das gröbste zu verhindern. Viele Admins werden davon ein Lied singen können, dass diese Protokolle meist wenig Spaß bereiten.

Einer der Vorkehrungen heißt SMTP-Auth. Ist das aktiviert, kann man nur noch nach einem gültigem Login seine Mails versenden. Dies ist üblicherweise bei allen größeren Providern der Fall.

Die Abhörung kann man als Admin hingegen nicht verhindern – zumindest nicht auf der gesamten Strecke von Sender zum Empfänger. Was man machen kann, ist dem vorhergehenden und nachfolgenden Knoten anzubieten, zumindest auf dieser Teilstrecke zu verschlüsseln. Das geht mit SMTPS oder STARTTLS.

Die oben genannten prinzipiellen Probleme von Mail bleiben aber weiterhin bestehen: Mail ist nicht vertrauenswürdig. Auch wenn das IZ die Sicherheitsvorkehrungen verschärft, werden sie an diesem prinzipiellen Problem nichts ändern können.

(Was möglicherweise machbar ist, ist dass Mails von …@hs-karlsruhe.de an …@hs-karlsruhe.de abgesichert werden können, in dem SMTP-Auth, SMTP-Header und Mail-Header übereinstimmen müssen. Aber ob dies mit gängigen Mailservern einfach machbar ist, kann ich nicht allerdings beurteilen.)

Wenn man ehrlich sein will, muss man seinen Nutzern daher nahelegen, Verschlüsselung und Signierung zu benutzen. Über solch eine asymmetrische Verschlüsselung kann man feststellen, ob eine Mail wirklich von einem bestimmten Absender kommt. Wie das geht, wird beispielsweise auf netzpolitik.org („Anleitung: so verschlüsselt ihr eure E-Mails mit PGP“) erklärt.

soziale Implikationen

Ein weiterer interessanter Aspekt, der an dieser hauptsächlich technischen Hochschule mit hohem Männer-Anteil zu tragen kam, war dass der Zufall hauptsächlich Männer mit Männern verkuppeln wollte ;-)

Hier gab es wohl auch die ein oder andere Anfeindungen als Antwort (die ich mal dreist aus einer Facebook-Gruppe kopiert habe):

Digger ist das dein ernst da wo ich herkomme werden homos gehängt ! Komm mal zu dir . Ich muss dich enttäuschen aber ich bin Hetero

Der Herr ist wohl nicht nur kompetenzbefreit, sondern auch ein homophobes Arschloch. Bleibt zu hoffen, dass das ein Einzelfall war. Es wurden nämlich auch einige nette Antworten gesichtet – und das ist doch auch schön! :-)

Rückmeldung der Hacker

Vom oben bereits genannten Host „schinderhannes“ kam bei mir um 20:48 eine Mail unter dem Absender „IZ-Benutzerberatung“ an. In dieser wird das Vorgehen so bestätigt, wie ich es hier vermutet hatte:

From: iz-benutzerberatung {at} hs-karlsruhe.de

Hi Marc,

wir haben deinen Blogeintrag mit Freude gelesen. Toller Artikel! Du hast mit deiner Erklärung unserer Vorgehensweise komplett ins Recht.
Im Anhang an diese Mail senden wir den Quelltext unseres kleinen Python-Skriptes. Wenn du Lust hast das in deinen Artikel einzubauen, darfst du das gerne tun.

Viele Grüße vom Congress!

hsspam.py

Das Skript

Im Prinzip macht das Skript folgendes: Es schickt an alle Nutzer der HsKA genau 1 Mail. Der Absender ist dabei zufällig. Es kann also sein, dass im Namen von „mami0003“ entweder 0, 1 oder viele Mails verschickt wurden.

Aufklärungsmail der Hacker

Es kam um 21:13 auch noch eine weitere Mail, die allerdings wohl nicht an alle ging. Zumindest nicht an mich. im Spam landete. (Danke an einball für die Weiterleitung.)

Ohai from the #30C3!

Die vorherige Mail war, wie ihr hoffentlich alle gemerkt habt, ein lustig gemeinter Scherz.

Wir haben eure Kommentare auf Facebook und Co mit einem dicken Grinsen auf dem Gesicht verfolgt. Auf Grund der vielen Verwirrungen die es aber darum gab und angeblichen Meldungen „der HSKA-Server sei gehacked worden“ (unter anderem vom AStA) haben wir uns dazu entschieden das aufzuklären.

Die technischen Aspekte hat Marc Kohaupt in seinem Blog [1] schon schön erklärt, weshalb wir es hier verzichten darauf einzugehen. Wir haben ihm unseren Quellcode [2] zukommen lassen um den Artikel zu vervollständigen.

Zu den Details:
* Alle Daten die wir dafür verwendet haben sind quasi hochschulöffentlich und können von jedem Studenten eingesehen werden. Wir haben die Daten nicht weitergegeben.
* Wir haben keine Passwörter „geknackt“ oder waren im Besitz solcher. Wir hatten lediglich euer Kürzel und euren Namen ausgelesen. Diese Daten wurden nach dem Versenden vernichtet.

Zum Warum?:
* Warum nicht?
* Weil wirs können!
* Weil wir darauf hinweisen wollen wie unsicher die Hochschulinfrastruktur ist.
* Weil wir wollen, dass sich das ändert!

Vielleicht hat das IZ ja jetzt endlich mal einen Grund das zu fixen.

Unabhängig davon möchten wir auch allen nochmal die Sicherheitstipps im oben erwähnten Blog [1] nahelegen. Signiert eure Emails!

Viele Grüße vom Congress!

[1] http://blog.debuglevel.de/liebesgruesse-vom-congress/
[2] http://sprunge.us/OLSU?python

Kommentare, Ethik und Disclosure

Da hier einige KommentatorInnen meinen, sie müssten wegen der Aktion den/die Hacker, andere KommentatorInnen oder mich von der Seite anpöbeln:

Man kann nun natürlich diskutieren, ob das noch mit der Hackerethik konform geht. Man muss festhalten, dass keine eurer Mails oder sensible Daten abgerufen wurden. Das was hier passiert ist, geschieht auch täglich beim Versand von Spam mit gefälschtem Absender.

Prinzipiell kann man auch fragen, wie hoch der „hack value“ ist – aber das ist wohl eine Geschmacksfrage. Die Meinungen liegen irgendwo zwischen „Scriptkiddies“, „notwendiger Wink mit dem Zaunpfahl“, „humorlos“ und „humorvoll“.

Es kam auch der Hinweis auf responsible disclosure auf. Dies bezeichnet den Vorgang, dass man Sicherheitslücken eine Zeit geheim hält bis sie behoben sind.

Solch ein responsible disclosure habe ich hier nicht durchgeführt. Den Vorfall habe ich hier dokumentiert, weil er in seiner Absurdität lustig ist und sich nebenbei die Chance ergab, ein bisschen technische Hintergrundinformationen über diese Problematik zu vermitteln. Dies ist mir insbesondere ein Anliegen in Anbetracht der seit Anbeginn von „Mail“ existierenden Problematik der Absender/Empfänger-Verfälschung und der seit diesem Jahr bekannt gewordenen Überwachung durch diverse Geheimdienste.

Diese Dokumentation macht die bestehenden Probleme (bei Mail allgemein, oder der HsKA im speziellen) weder besser noch schlimmer. Es soll nur die Problematik aufzeigen und euch dafür sensibilisieren, welche Gefahren drohen und wie man sie eventuell bemerken und umgehen kann.

Überarbeitung

Da der Artikel in seiner Urfassung ziemlich schnell zusammengetragen wurde, habe ich ihn im Laufe des Tages ein paar mal überarbeitet und erweitert. Ich hoffe, dass er jetzt auch für Nicht-InformatikerInnen lesbar und verständlich ist. Über Rückmeldung in den Kommentaren würde ich mich freuen.

Update 14.02.2014

Hallo liebe Leserinnen und Leser, die ihr von Twitter, golem.de und anderen Seiten kommt! Nach wie vor freue ich mich natürlich über eine sachliche Diskussion und Hinweise in den Kommentaren. Damit allerdings nicht noch mehr Schrott in die Kommentare wandert, habe ich diese auf Moderation gestellt. Ich hoffe das ist halbwegs okay :)

Schöne Weihnachten

Weihnachtsfzibaum
Weihnachtsfzibaum

Die App: TelCoApp

Die App nennen wir – in Ermangelung eines fancy Namen – nach dem, was sie tut. TelCoApp. Damit ist auch schon gesagt, was sie unterstützen soll. Telefonkonferenzen.

Wie sieht diese Unterstützung aus? Logisch aus den bisherigen Postings fortgesetzt wird dies wohl etwas mit Telefonkonferenzen, MoodMaps und EKG zu tun haben. Und so ist es auch. Was kommt also dabei raus, wenn wir MoodMaps, EKG und TelCos in eine App packen? Das:

Der Hauptbildschirm der TelCoApp mit Diagramm, MoodMap und Chat.
Der Hauptbildschirm der TelCoApp mit Diagramm, MoodMap und Chat.

Rechts oben sehen wir die MoodMap. Auf die kann man touchen und damit seine Stimmung eingeben. Links oben sieht mein einen Graphen, der die Herzfrequenzvariabilität (HRV – heart rate variability) anzeigt. Die fällt aus dem EKG-Sensor raus und per Bluetooth in die App rein. Unten ist ein Chat. Unwichtig.

Die App leitet die HRV dann an einen XMPP Server (das ist das Protokoll, über das z.B. auch der Facebook-Chat läuft) weiter. Von dort aus wird ein Mittelwert aus allen Teilnehmer an alle gesendet. Man bekommt also eine Team-HRV, welche den durchschnittlichen Gemütszustand repräsentieren soll. Prinzipiell wäre wohl auch eine Anzeige der durchschnittlichen Stimmung sinnvoll – die hat es aber wohl nicht mehr in die App geschafft.

Was ich im Zuge meiner Arbeit mit dieser App anstelle, und warum ich das anstelle: später.

Vorgänger der App: MoodMap App

Dann will ich mal anschneiden, an welcher App ich im Zuge meiner Arbeit am Mirror Project arbeite: Keine der dort aufgeführten. :P Im Grunde ähnelt sie aber stark einer der Apps, bzw. ist eine Weiterentwicklung: MoodMap App (Bilder dort).

MoodMap also… okay… eine MoodMap ist eine zweidimensionale Karte. Auf der einen Dimension wird Arousal (körperliche Erregung), und auf der anderen Dimension die Valence (positive/negative Empfindung) abgetragen. Dabei kommt beispielsweise raus „ich fühle mich energiegeladen und echt mies“ (= Ärger).

Die MoodMap App wird collaborative eingesetzt – der dargestellte UseCase ist eine Telefonkonferenz. Jeder stellt also seine Stimmung ein, und kann so eine Übersicht über die Team-Stimmung und die eigene im Vergleich gewinnen. Ein weiterer wichtiger Punkt ist die Reflexion und was man daraus lernen kann (dazu gibt’s bereits einen älteren Blogbeitrag).

Mit einer Weiterentwicklung dieser App arbeite ich gerade. Diese Weiterentwicklung existiert bereits – ich selber muss also nicht entwickeln, sondern veranstalte damit ein psychologisches Experiment. Wie diese App aussieht, was sie macht, und was ich damit anstelle… demnächst.

Forschungsprojekt: Mirror – Reflective Learning at Work

Im letzten Beitrag habe ich kurz erläutert, in welchem Forschungsbereich ich stecke – aber noch nicht in welchem Forschungsprojekt. Mirror.

Das Mirror Project ist ein Forschungsprojekt der EU im sogenannten 7th Framework Programme for Research and Technological Development (darüber wird jede Menge Zeug finanziert). Mirror hat den Untertitel Reflective Learning at Work. Nehmen wir das mal auseinander:

at Work: Naja – eben der Kontext des Arbeitens bzw. der Arbeitsstelle.

Beispiel: Ich bin Projektleiter eines kleinen Entwicklerteams bei der IT Mega Consulting GmbH und wir skypen oft mit unseren Projektpartnern.

Reflective: Beim psychologischen/philosophischen Prozess der Reflexion (auch: Selbstbeobachtung, Introspektion) beobachtet und analysiert man die eigenen Verhaltensweisen, Gedanken, Emotionen und Beweggründe.

Beispiel: Auf die Skype-Sessions habe ich wenig Lust und mich graut es immer davor. Meistens schiebe ich sie weit möglichst hinaus. Warum? Mal reflektieren: Ich bin während den Skype-Sessions ziemlich oft gestresst, weil der Projektpartner immer neue Wünsche hat, die Entwickler ohnehin schon überausgelastet sind und ich nicht weiß wie ich das alles managen soll. Aha!

Learning: Oft führt diese Reflexion dann zu einem Erkenntnisprozess und zum Bestreben, eine Verhaltensänderung durchzuführen.

Beispiel: Ich lege wöchentlich eine fixe Skype-Session fest. Den Projektpartner weise ich im Einzelgespräch darauf hin, dass Wünsche okay sind, aber das Projektende verzögern. Zusammen priorisieren wir die Teilaspekte des Projektes, damit eine stetige Auslastung aber keine Überlastung eintritt.

Also durch Selbstbeobachtung dazulernen und sich verbessern. Das (oder so ähnlich) ist Reflective Learning at Work.

Was im Untertitel eigentlich noch fehlt, ist dass das mit technischer Unterstützung geschehen soll. Wie aber kann technische Unterstützung bei diesem Ziel helfen? Dafür werden bei Mirror eine Fülle an Apps entwickelt. Diese sollen über die verschiedensten Herangehensweisen dem Nutzer helfen, mehr über sich zu erfahren.

Ein Beispiel dafür ist das Live Interest Meter (Bilder dort). In dieser App nehmen eine Dozentin und die Zuhörer teil. Die Zuhörer können nun der Dozentin Rückmeldung geben, ob sie zu schnell/okay/langsam ist und ob man den Stoff gut/schlecht versteht. Die Dozentin kann das sehen und sich dann gegebenenfalls Gedanken darüber machen, wie sie den Stoff nächstes mal anders aufbereitet. Sprich: Sie lernt.

Teaser: Beim nächsten mal dann, bei welcher App ich mitmische.

Forschungsbereich: Medizinische Informatik

Im letzten Beitrag habe ich kurz auf die Forschungsbereiche des FZI verwiesen, aber noch nicht angesprochen in welchem Kasten ich da stecke: Medizinische Informationstechnik. Zumindest irgendwie im weitesten Sinne. Das hat weitaus weniger mit Blut, Tumoren und Herzschrittmachern zu tun als es sich anhört. Der nachfolgende Abschnitt von der Website des FZI erklärt das so schön, dass ich ihn einfach zitiere:

Daneben steht die Nutzung medizinischer Sensorik für nicht-medizinische Anwendungen verstärkt im Interesse der Forschung am FZI. So entwickeln wir auch Biofeedback-Anwendungen zur Unterstützung von Lernprozessen im Bereich Technology Enhanced Learning (TEL) […] (Quelle)

Okay. Was ist solch eine medizinische Sensorik in meinem konkreten Fall? Ein EKG-Sensor, den man sich mit einem Gurt um die Brust schnallt und der dann die Herzfrequenz aufzeichnet (und noch paar für meinen Zweck irrelevante Sachen wie Luftdruck und Beschleunigung). Bei meinem Sensor handelt es sich um den ekgMove von movisens (Bilder dort).

Die Sensorik ist geklärt, was aber ist die nicht-medizinische Anwendung? Irgendwie so etwa das, wo es nicht um akute starke gesundheitliche Probleme geht. Da sollte man doch lieber zum Arzt. Wir spielen forschen daran herum und probieren nützliche Anwendungsgebiete aus.

Teaser: Im nächsten Posting sage ich dann auch, in welchem Forschungsprojekt ich beteiligt bin.

am FZI sind die Tassen Public Domain

Seit dem 1. Dezember 2013 bin ich nun als Masterand am Forschungszentrum Informatik am Karlsruher Institut für Technologie. Kurz FZI.

Hier am FZI werden so circa verschiedene Systeme konzipiert und Prototypen entworfen. Auf der Website findet man eine schöne Übersicht über die aktuelle Forschung. An welchem dieser Kästchen ich beteiligt bin – dazu in einem späteren Posting.

Grob geschätzt arbeiten hier so in etwa 100 Personen. Die ForscherInnen fallen wohl meistens nach ihrem abgeschlossenen Studium direkt aus der Uni ins FZI hinein. Sprich: Alles sehr jung hier.

Und natürlich auch ein bisschen nerdig. Auf die Frage, ob die Tassen im Schrank privat oder für alle zugänglich sind: „Die sind wohl public domain.“ Ich glaube, mir gefällt es hier.

reconnect script for TD-W8960NB

In germany, our ISPs provide us a nasty thing called „24h reconnect“. Every 24 hours, the DSL connection is reseted (don’t ask why. They claim to have good reasons…). Certain manufacturers of DSL routers/access points adapted to the german market and provide a feature to reconnect at a certain time (like 04:00am when nobody’s working).

Unfortunately my cheap TP-Link router does not have such a feature. So I wrote a small script which is called via crontab from my RaspberryPi at 04:00am

#!/bin/bash

sessionKey=$(curl --user admin:password "http://192.168.1.1/resetrouter.html" 2> /dev/null | grep sessionKey | cut -d "'" -f 2)
#echo $sessionKey
url="http://192.168.0.1/rebootinfo.cgi?"$sessionKey
#echo $url
curl --user admin:password $url &> /dev/null

web2py AJAX is not working if the proper URL has not been used

At the moment, I’m playing around with web2py (a nice full-stack bundle to develop Python Web Applications).

I created a simple AJAX button which just shows a simple message:

AudacityControlWeb/views/default/index.html:

[...]
<form>
    <input id="set_mark_newparagraph" type="button" value="{{=T('mark: new paragraph')}}" onclick="ajax('set_mark_newparagraph_onclick','leer','output')" class="btn-large btn-huge">
</form>
[...]

AudacityControlWeb/controllers/default.py:

[...]
def set_mark_newparagraph_onclick():
    response.flash=T('marked a new paragraph')
    return T('marked a new paragraph')
[...]

I called http://127.0.0.1:8000/AudacityControlWeb/default/index and clicked the button. Everything is working perfect.
As I’m developing this tool for an Android device, I also called it on my Android Chrome. Of course I’m lazy and just called http://127.0.0.1:8000/AudacityControlWeb instead of the whole URL. The page shows up, as the default controller with the index action is invoked automatically.
But it didn’t work. The button just did not do anything. I connected my Android via USB Debugging and found out it tried to call http://127.0.0.1:8000/set_mark_newparagraph (which, of course, does not work).
So remember, always call the full URL http://127.0.0.1:8000/AudacityControlWeb/default/index instead of being lazy.

calling Bash script in Python / missing shebang

I recently tried to call a „bash“ script (actually it just was rather a batch script with some commands) out of a python script:

subprocess.call("/home/tux/bin/foo.sh")

Unfortunately, it did not work:

OSError: [Errno 8] Exec format error

The problem was, that foo.sh missed the „shebang-line“

#!/bin/bash
[...]

Serie von tarballs entpacken und zusammen neu packen

Hat man eine Serie von Tarballs (z.B. durch Backups auf einem Webspace), dann sind diese in der Regel nicht inkrementell und werden somit immer größer (und beinhalten zugleich größtenteils das selbe).

Um den Platzbedarf zu vermindern kann man alle Tarballs entpacken und neu zusammenpacken:

als root (weil sonst gegebenenfalls Berechtigungen verloren gehen):

# entpacken
for i in *.tar.gz; do
  mkdir $i.dir;
  tar -xvzf $i -C $i.dir;
done

# eventuell Deduplikation
freedup -d -g -l -p -u -T -0 .

# packen
# z.B. mit 7zip "compact archives"
# tar mit gzip bringt hingegen keinen Vorteil, da die redundanten zu weit voneinander entfernt sind.

Aufnahme von Skype-Interviews mit getrennten Kanälen

Möchte man ein Gespräch mit Skype aufnehmen, dann steht man vor gewissen Problemen. Die API von Skype erlaubt zwar das Abgreifen beider Tonspuren – mit etwas Pech ist die Aufnahme aber dann offsync (also beide Spuren nicht synchron).

Mit PulseAudio hat man unter Linux aber einen Soundserver, mit dem man dies relativ gut realisieren kann.

pactl load-module module-null-sink sink_name=mako_mix
pactl load-module module-loopback sink=mako_mix channels=1 channel_map=front-left  remix=false latency_msec=100
pactl load-module module-loopback sink=mako_mix channels=1 channel_map=front-right remix=false latency_msec=100

Dieser Schnipsel erstellt einen neuen Mix/Sink („mako_mix“), und zwei Loopbacks welche auf diesen weiterleiten. Dabei wird jeweils nur der linke bzw. der rechte Kanal weitergeleitet.

Nun kann man „pavucontrol“ aufrufen, bei „Aufnahme“ alle Geräte angezeigt werden, und eines der beiden neuen Devices auf den Monitor stellen (der andere steht bei mir bereits auf dem Mikrofon).

Nun kann die Aufnahme gestartet werden:

parecord -v -d mako_mix.monitor --channels=2 --channel-map=front-left,front-right --no-remix > record.raw

Anschließend kann es in eine Wave Datei konvertiert werden, damit es in Audacity o.ä. bearbeitet werden kann:

sox -c 2 -r 44100 -s -2 -t raw record.raw -t wav record.wav

(eventuell muss auch die Sampling Rate von 44100 auf etwa 48000 geändert werden)

Audio-Setup zum Podcasten

Mit dem Zeugerzähler gehe ich seit kurzer Zeit meinem heimlichen Faible nach, Sprache aufzunehmen und Texte einzusprechen.

Das passiert alles natürlich auf einem extrem amateurhaftem Niveau, und ebenso sieht das Audio-Setup dazu aus:

Das Mikrofon ist bisher einfach ein handelsübliches (Gamer?)-Headset, dessen Preis ich immer auf 15€ geschätzt habe. Das Produkt, dass bei Amazon dem am nächsten kommt ist das Speedlink Medusa.

Da interne Soundkarten bzw. deren Mikrofon-Eingänge oft unter aller Würde sind, habe ich mir ein paar externe USB Soundkarten für jeweils ein paar Euro geholt, ausprobiert und die mit dem wenigsten Rauschen dann weiter benutzt. Vom Aussehen her, könnte es diese mit C-Media Chip sein.

Als Audiorekorder dient mein Ubuntu 12.10 mit PulseAudio und Audacity (oder auch Windows 7 mit Audacity), dass ich auch zum Arbeiten verwende. Das Linux hatte anfangs noch das Problem, dass sich Audacity bei der Aufnahme hin und wieder verschluckte – was sich aber gelegt hat, nachdem ich darauf geachtet habe, dass das System sonst mit nichts weiter beschäftigt ist.

Das größte Manko an diesem Setup war, dass das Mikrofon zum einen keinen Poppschutz hatte und zum anderen keine Möglichkeit bestand, das Audiosignal direkt wieder auf die Kopfhörer zu legen – sprich: kein Monitor (das ist bei Podcasts in der Regel auch egal – wenn man aber mit der Stimme spielen und neues Ausprobieren möchte, ist das vermutlich von Vorteil).

Als sich dann ein Kabelbruch am Headset ereignete, habe ich das als Chance genutzt, mein Setup von Ultra-Low Budget auf Low Budget anzuheben.

Nach längerem Nachdenken, was es denn nun werden soll, habe ich mich für ein Samson Go Mic entschieden:

  • es kann per USB direkt an den PC angeschlossen werden
  • ermöglicht ein Abhören des Signals über Klinkenstecker
  • hat (hoffentlich) eine besser Aufnahmequalität als das bisherige dynamische Headsetmikrofon ;-)

(Passend dazu habe ich mir einen neuen, beliebigen Kopfhörer gekauft.)

Neue Aufnahmen mit diesem Setup stehen bisher allerdings noch aus, so dass ich erst in einigen Tagen mehr darüber sagen kann, ob es eine Verbesserung darstellt.

Andere Ideen, die weitaus flexibler, aber auch weitaus komplexer und teurer gewesen wären, beinhalteten ein Großmembran Kondensatormikrofon und einen Mixer, welcher die Möglichkeit geboten hätte, bei Bedarf auch ein zweites Mikrofon für einen weiteren Gesprächsteilnehmer anzustöpseln. Allerdings bin ich dann zu dem Schluss gekommen, dass ich hier erst noch weitere Erfahrung sammeln möchte und bei eventuellem, zukünftigen Bedarf dann ein komplettes neues Setup anschaffe.

.htpasswd geht nicht wegen fehlendem +x Recht

Gerade bin ich wieder in einen beliebten Fehler gelaufen: Wenn ein anderer User (z.B. „apache“) auf eine Datei zugreifen will, dann müssen alle Verzeichnisse im gesamten Pfad das +x Recht besitzen.

Hat man also beispielsweise die Datei /home/$user/html/$foo/.htaccess, in der folgendes steht:

AuthName        "Speak, friend, and enter."
AuthType        Basic

#funktioniert nicht:
#AuthUserFile    /home/$user/html/$foo/.htpasswd

#funktioniert:
AuthUserFile    /var/www/virtual/$user/html/$foo/.htpasswd

require valid-user

während /home/$user/html ein Symlink auf /var/www/virtual/$user/html ist, kann apache unter Umständen nicht auf die .htpasswd zugreifen.
Der Umstand, unter dem das nicht funktioniert, ist, dass apache nicht auf /home/$user zugreifen kann, weil die Rechte entsprechend restriktiv gesetzt sind. Für /var/www/virtual/$user sind jedoch die Rechte so gesetzt, dass dies funktioniert.

Unter http://unix.stackexchange.com/questions/5860/how-do-i-recursively-check-permissions-in-reverse werden Tools diskutiert, mit denen rekursiv die Berechtigung der übergeordneten Verzeichnisse geprüft werden kann.

Kurzum: Die Rechte der übergeordneten Verzeichnisse überprüfen. :)

Podflow

In den letzten Tagen habe ich ein Plugin für den Podlove Publisher geschrieben: Podflow.

Die Idee hinter Podflow ist es (wie im Grunde hinter dem gesamten Podlove Projekt), die Veröffentlichung von Podcasts so einfach wie möglich zu machen.

Podflow

Hierzu findet in Podflow ein, im Grunde ziemlich einfache, Integration der Auphonic API und Podlove statt:

  • der Nutzer lädt im ersten Schritt die Quelldatei über Podflow hoch
  • setzt im zweiten Schritt die Metadaten (Titel, Subtitel und Beschreibung der Episode) und
  • wählt im optionalen dritten Schritt ein Auphonic Preset aus, sofern er mehr als eins hat

dazwischen und danach passiert im Hintergrund automatisch die Integration:

Podflow…

  • … lädt über die REST API die Presets von Auphonic herunter
  • … lädt die Audiodatei zu Auphonic hoch
  • … wartet bis Auphonic mit der Bearbeitung fertig ist
  • … lädt die Ergebnisse von Auphonic herunter
  • … veröffentlicht die neue Episode

Auf YouTube ist eine kurze Demonstration des Plugins zu finden.

Was die Weiterentwicklung von Podflow angeht, bin ich mir allerdings noch etwas unschlüssig. Ich gehe im Grunde davon aus, dass Tim Pritlove beziehungsweise das gesamte Team hinter Podlove selber bereits einen solchen möglichst simplen Workflow anstrebt. Daher sehe ich Podflow derzeit eher als ein Proof of Concept, wie einfach die Veröffentlichung einer neuen Episode gestaltet werden kann.

Vielen Dank an dieser Stelle an die Entwickler hinter Podlove und Auphonic! Vielleicht kann ja sogar der ein oder andere Codeschnipsel aus Podflow im Podlove Publisher wiederverwendet werden.

Für Interessenten sind die Sourcen auf GitHub zu finden. Zum gegenwärtigen Zeitpunkt kann das Verzeichnis einfach in das „modules“ Verzeichnis von Podflow eingefügt und anschließend das Modul in den Einstellungen von Podflow aktiviert werden.

Der Funktionsumfang ist bisher allerdings eher begrenzt und noch nicht alle angesprochenen Features so umgesetzt, wie es wünschenswert und sinnvoll wäre.

Filme über SSH/SFTP-Server auf Android streamen

Möchte man auf seinem Android Filme anschauen, die nicht lokal auf dem Gerät liegen, sondern über SSH/SFTP auf einem anderen System zugänglich sind, steht man vor zwei Problemen:

  • Zugriff auf den SFTP-Server
  • Streaming des Films ohne den kompletten Film zu cachen

Eine Kombination, die dies möglich macht sind die beiden Apps „ES File Explorer“ und „MoboPlayer“.

MySQL CSV Export mit n:m Beziehung und WordPress CSV Import

Als ich von meinem alten Blogsystem (Eigenentwicklung) auf WordPress umstellen wollte, ergab sich das Problem, wie ich meine alten Postings möglichst verlustfrei in WordPress importieren kann.

Das Problem stellte dabei eine N:M Beziehung in meinem Altsystem dar: Ein Posting hat mehrere Tags und jedes Tag kann natürlich von mehreren Postings verwendet werden.

Die Grundidee war dabei die Tabelle als XML zu exportieren und die N:M Beziehung dort einfach denormalisiert als XML-Elemente unterhalb des Postings abzulegen. Leider habe ich in MySQL nun nichts gefunden, mit dem man Daten in XML umformen kann.

Stattdessen habe nun die Tags eines Postings mit Kommas in einer Spalte verbunden, was man dann als CSV exportieren kann.

Dies kann man bewerkstelligen, in dem man den folgenden Code an seine Bedürfnisse anpasst:

SELECT
  notes.*,
  GROUP_CONCAT(tags.name) as taglist
FROM
  notes
LEFT JOIN
  notes_has_tags ON notes_has_tags.note = notes.id
LEFT JOIN
  tags ON notes_has_tags.tag = tags.id
GROUP BY
  notes.id

In MySQL kann man das Ergebnis nun einfach als CSV exportieren (und darauf achten, dass man das Semikolon als Spaltentrenner verwendet).

In WordPress kann man das CSV nun absolut simpel mit dem „Wp Ultimate CSV Importer“ importieren. Dieser erkennt die Komma-separierten Tags und kommt auch mit Zeilenumbrüchen in CSV Files klar. Allerdings will man womöglich darauf achten, dass man diese Postings nicht als Draft importiert – sonst geht der Veröffentlichungszeitpunkt verloren.

kein Strich bei wiederholendem Autor in BibLaTeX mit authoryear

Wird hintereinander mehrmals der gleiche Autor aufgezählt, so ersetzt der BibLaTeX-Style „authoryear“ diesen durch einen Strich. Dies lässt sich sehr einfach ändern, in dem man folgenden Code einfügt:

\makeatletter
\newbibmacro*{bbx:dashcheck}[2]{#2}
\makeatother

umbenannter Key mit git

Hat man gemäß der Anleitung bei github (oder irgendwo anders) einen Key hinterlegt, ihn aber nicht mit dem standardmäßigen „id_rsa“ benannt (sondern z.B. „~/ssh/github“), dann wird man von git abgestraft, da der Key natürlich nicht gefunden wird.

$ git remote add origin git@github.com:johndoe/foobar.git
$ git push -u origin master
Permission denied (publickey).
fatal: The remote end hung up unexpectedly

Man kann nun aber diesen Key dem ssh Agent bekannt machen, dann funktioniert es:

$ ssh-add github
Enter passphrase for github:
Identity added: github (github)
$

Hardlinks einer Datei finden

$ ls -li
[...]
397653 -rwxr-xr-x 2 root root 4285 2011-08-02 10:54 foobar
[...]

$ find / -xdev -inum 397653
/usr/lib/foo
/usr/lib/foobar

Leeres kompiliertes Template bei fehlendem Lesezugriff

Die Template-Kompilierung von phpBB3 liest Daten mittels file_get_contents() aus. Stößt diese Funktion auf irgendeinen Fehler (so zum Beispiel fehlende Leserechte), gibt sie lediglich FALSE zurück, wirft aber keinen Error.
Dies führt dazu, dass phpBB3 annimmt, dass das Template leer sei und daher ein leeres Kompilat generiert.

Python und HTTP Proxy

Wer Python-Skripte hinter einem HTTP-Proxy benutzen möchte, kann dies über das setzen einer Umgebungsvariable machen:

export http_proxy=http://username:password@proxy.server.com:8080/

Bücher bzw. alle Kapitel von SpringerLink gesammelt herunterladen

Wer SpringerLink benutzen möchte, wird sich schnell daran aufhalten, alle Kapitel eines Buches manuell herunterzuladen. Mittels folgenden Skriptes kann man dies automatisieren; die PDFs werden anschließend zudem zu einem PDF zusammengefügt.
http://milianw.github.com/springer_download/

Skript um Mono 2.10 zu installieren

Hier ein Skript, um verschiedene Mono-Versionen (z.B. 2.10, 2.8, 2.6) parallel unabhängig von der Paketverwaltung zu installieren:
http://github.com/firegrass/mono-installer-script

Snap wie unter Windows 7 für Gnome

Von Windows 7 kennt man die Snap-Funktion, die Fenster am linken, rechten und oberen Bildschirmrand maximieren kann. Das kann man auch relativ einfach für Gnome bzw. Compiz nachbauen:
http://linuxundich.de/de/software/aero-snap-mit-gnome-und-compiz/

ghostscript 8.71 hat Probleme mit ps2pdf

ghostscript 8.71, welches beispielsweise in Ubuntu 10.10 ausgeliefert wird, hat einen Bug in der pdf-Umwandlung. Dieser führt dazu, dass das PDF zwar scheinbar den richtigen Text enthält, im Hintergrund aber etwas anderes hinterlegt ist.
Dies führt dazu, dass man den Text mit Adobe Reader nicht durchsuchen und kopieren kann. Die Folgeversion ghostscript 9.00 behebt diesen Bug.

man-pages auf Englisch

Viele Distributionen bieten mittlerweile (veraltete) Übersetzungen der man-pages an. Um dies zu unterbinden, kann man in der ~/.bashrc folgendes hinzufügen:

alias man="LANG=en_US.UTF-8 man"

Verändern von .deb Paketen

$ dpkg-deb -e ../miktex-tools-2.8.3541-1-i386-linux.deb
$ dpkg-deb -x ../miktex-tools-2.8.3541-1-i386-linux.deb .
[...Veränderungen vornehmen...]
$ dpkg -b . miktex-tools-2.8-changed.deb

Vorlagen für LaTeX

Wissenschaftliche Arbeiten schreibt man oft mit LaTeX – das Layout etwas auszuschmücken und an deutsche Gepflogenheiten anzupassen, ist jedoch mitunter recht aufwändig.

Nachfolgend sind einige Vorlagen zu finden, die einen Rahmen für die eigene Arbeit darstellen können. Zu Beachten ist, dass manche Vorlagen auf doppelseitigen Druck (unterschiedliche Header auf gerade und ungeraden Seiten), manche auf einseitigen Druck (überall die gleichen Header; angeblich die bevorzugte Variante für wissenschaftliche Arbeiten) ausgelegt sind.

http://www.nm.ifi.lmu.de/teaching/Downloads/stud77.zip
http://www.hs-esslingen.de/static/326/Vorlage_wissenschaftliche_Arbeit.zip
http://staff.fh-hagenberg.at/burger/diplomarbeit/index.html

Lesezeichen von Nautilus/GTK

Liegen als Plaintext unter „~/.gtk-bookmarks“

Unicode in Python mit Pipes

Python gibt bei der Verwendung von Unicode und Pipes möglicherweise folgendes Problem aus:

"UnicodeEncodeError: 'ascii' codec can't encode character"

Mit der folgenden Einstellung wird „print“ die Ausgabe immer in UTF-8 kodieren:

import codecs, sys
sys.stdout = codecs.getwriter('UTF-8')(sys.stdout)

„Öffnen mit“-Assoziationen in Nautilus

Benutzerspezifische Einträge für das „Öffnen mit“ in Nautilus lassen
sich unter „~/.local/share/applications/mimeapps.list“ finden und
korrigieren.

Thunderbirds Tab-Leiste bei nur einem Tab verstecken

Möchte man, dass die Tab-Leiste in Thunderbird 3 ausgeblendet wird wenn nur ein Tab geöffnet ist, so kann man in about:config die Option

mail.tabs.autoHide=true

setzen.

Grip unter Ubuntu 10.10

Da ich Grip nach wie vor gerne benutze und Ubuntu 10.10 nach wie vor das Paket entfernt hat, habe ich das Debianpaket für Ubuntu „umgeschrieben“ (d.h. den Namen einer Abhängigkeit (libkrb53 auf libkrb5-3) korrigiert).
http://www.file-upload.net/download-3067422/grip_3.3.1-15-mako_i386.deb.html (Update: Link leider defekt)

Chainload von Grub1 auf Grub2

Ein Chainload auf Grub2 kann man wie folgt bewerkstelligen (warum es nicht mit „chainloader +1“ funktioniert, ist mir leider nicht so recht klar.):

title   Chainload von Grub1 auf Grub2
root    (hd0,6)
kernel  /boot/grub/core.img

Constraints einer Tabelle aktivieren bzw. deaktivieren in MSSQL

CREATE PROCEDURE sp_ConstraintState 
                    @TblName    VARCHAR(128),
                    @State        BIT = 1
AS
DECLARE @SQLState VARCHAR(500)
IF @State = 0
    BEGIN
        SET @SQLState = 'ALTER TABLE '+ @TblName + ' NOCHECK CONSTRAINT ALL'
    END
ELSE
    BEGIN
        SET @SQLState = 'ALTER TABLE ' + @TblName + ' CHECK CONSTRAINT ALL'
    END
EXEC (@SQLState)
GO

Aufruf via

exec sp_ConstraintState  'products',0

(Quelle: http://www.databasejournal.com/scripts/article.php/1459571/Disabling-or-Enabling-All-Constraints-of-a-Table-or-Database.htm)

DateTime des Monatsanfangs in MSSQL

Nicht schön, aber selten:

SELECT
    CONVERT
    (
        DATETIME,
        CONVERT(VARCHAR, DATEPART(year, GETDATE())) + '/' 
            + CONVERT(VARCHAR, DATEPART(month, GETDATE())) + '/'
            + '1',
        111
    ) AS Monatsanfang

Ergibt z.B. „2010-12-01 00:00:00.000“

Headings in ODT

In OpenDocument-Text werden Überschriften als

<text:h text:style-name="foo" text:outline-level="1">bar</text:h>

ausgezeichnet. Dabei ist zu beachten, dass „foo“ hier eine benutzerdefinierte Überschrift ist.
Bei mir war dies in einem Test allerdings nicht der Fall, sondern wurde als

<text:p text:style-name="foo">bar</text:p>

gespeichert. Die Ursache war, dass in OpenOffice.org keine Gliederungsebene in der Absatzvorlage der Überschrift definiert war.

XML formatieren

Mit

xmllint --format foobar.xml

kann man eine XML-Datei formatiert ausgeben lassen.

einfache topologische Sortierung

Beim Aufbau einer Abhängigkeitsliste stand ich vor dem Problem, eine Liste von Tabellen topologisch zu sortieren (damit keine Probleme mit Fremdschlüsseln auftreten).
Das macht man eigentlich mittels einer topologischen Sortierung, welche zu implementieren ich aber spontan keine Lust hatte. Stattdessen habe ich einen abgewandelten Postorder-Baumdurchlauf benutzt:

        /// <summary>
        /// Sortiert Tabellen nach ihren Abhängigkeiten
        /// </summary>
        ///
<param name="tables">alle Tabellen</param>
        /// <returns>kleinster Indices = Leaf, größte Indices = Roots</returns>
        private static List<TableDefinition> sortTableDefsByRelations(List<TableDefinition> tables)
        {    
            List<TableDefinition> order = new List<TableDefinition>();
            foreach (TableDefinition table in tables)
            {
                buildOrder(table, order, tables);
            }
            return order;
        }

        /// <summary>
        /// Baut rekursiv (postorder) eine Sortierung auf, in der die Tabellen hinzugefügt werden sollen
        /// </summary>
        /// <remarks>
        /// Nur abändern, wenn man sich sicher ist, dass man nichts kaputt macht ;^)
        /// </remarks>
        ///
<param name="table">Start-Tabelle</param>
        ///
<param name="order">Liste, in die die Sortierung angefügt werden soll</param>
        ///
<param name="allTables">alle Tabellen, in denen gesucht werden soll</param>
        private static void buildOrder(TableDefinition table, List<TableDefinition> order, List<TableDefinition> allTables)
        {
            //Wenn Tabelle bereits in der Sortierung ist, abbrechen (sollte funktionieren; primär für Performance)
            if (order.Contains(table) == true)
            {
                return;
            }
            List<TableDefinition> dependencies = getTableDependencies(table, allTables);
            foreach(TableDefinition dependency in dependencies)
            {
                buildOrder(dependency, order, allTables);
            }
            if (order.Contains(table) == false)
            {
                order.Add(table);
            }
        }

getTableDependencies() ist eine sehr spezifische Funktion, die mit dem Algorithmus an sich nichts zu tun hat. Sie gibt einfach alle direkten Abhängigkeiten einer Tabelle zurück.
Tabellen wiederrum sind im Datentyp „TableDefinition“ beschrieben, der ebenfalls spezifisch ist.

JPG in Film umwandeln

Prinizipiell geht folgender Befehl, jedoch scheint mplayer allergisch auf fehlerhafte JPGs zu reagieren. Daher vorher eventuell noch mal alle neu konvertieren.

mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800

Multithreading auf der Konsole

Möchte man mehrere Programme gleichzeitig (z.B. im Kontext eines Batch-Jobs) ausführen (das will man, wenn man mehr als eine CPU hat), so kann man zu folgenden Tools greifen:

xargs mit dem Argument -P
xjobs
parallel bietet zusätzlich ein Tool an, dass über ssh andere PCs ansteuern kann.
ppss

Highlighting auf der Konsole

Hier ein kleines Skript, welches Input auf der Standardeingabe annimmt, alles wieder ausgibt, und das gesuchte Wort farbig markiert.

#!/bin/bash
TEXT=$*
grep --color=always -E "$TEXT|$"

Aufruf:
cat /var/log/messages | highlight.sh kernel

Im Grunde macht das Ding also so etwas wie die folgende Zeile, nur ohne zu filtern:

grep --color=always 'kernel' /var/log/messages

automatischer transparenter Proxy

In der YaCy-Hilfe habe ich gerade folgendes gefunden:
„Unter Linux können Sie Ihre Firewall darauf einstellen, alle HTTP-Verbindungen transparent an YaCy weiterzuleiten indem Sie diese iptables-Regel verwenden.:
$ iptables -t nat -A PREROUTING -p tcp -s 192.168.0.0/16 --dport 80 -j DNAT --to 192.168.0.1:8080

SSL-unfähigen Client mit SSL-fähigem Server verbinden

Möchte man einen Client, der kein SSL kann, mit einem Server verbinden, der SSL spricht, kann man das kleine Tool stunnel benutzen:
$ sudo stunnel -f -c -d 110 -r login.hs-karlsruhe.de:995
startet den „Wrapper-Server“, der eine SSL-Verbindung zum Server aufbaut, und eine unverschlüsselte Verbindung lokal anbietet.
Nun kann man z.B. mit netcat localhost 110 auf den Server zugreifen, ohne dass man selber etwas mit SSL zu tun hat.

Postfix das Verschlüsseln beibringen (optional: mit CAcert)

Um den Nachrichtenaustauschen zwischen Client und SMTP-Server zu verschlüsseln, kann man mit Postfix TLS einsetzen. Wie genau, möchte ich hier nicht erklären, sondern auf einige gute Howtos hinweisen:
Grob habe ich mich an http://wiki.debian.org/PostfixAndSASL gehalten – allerdings scheinen mir da Stücke vom Code zu fehlen. Diesbezüglich kann man sich gut an http://yocum.org/faqs/postfix-tls-sasl.html halten, und dort bei Schritt 8 einsteigen (und Schritt 11 evtl. überspringen).
Was dort nirgends steht, ist dass

tlsmgr unix - - n 1000? 1 tlsmgr

in „/etc/postfix/master.cf“ nicht auskommentiert sein darf.
Desweiteren Wissenswert: Die Zertifikate müssen nur für root zugänglich sein, da Postfix diese noch einliest, bevor es seine root-Rechte abgibt.

Will man seine Zertifikate von CAcert signiert haben, so ist dieses Howto zu empfehlen: http://koti.kapsi.fi/ptk/postfix/postfix-tls-cacert.shtml

Rekursiv alle neuen Dateien zum SVN hinzufügen

$ svn add .
svn: warnung: ».« befindet sich bereits unter Versionskontrolle
$ svn add --force .
A         foo.txt
A         bar/baz.txt
...

Ersatz für „which“ in Windows

Unter Unix ist gehört das Kommando

which

zu den absoluten Basistools: Es zeigt an, wo sich ein Programm innerhalb vom PATH befindet.
Man kann es allerdings nachbauen:

for %x in (java.exe) do @echo %~$PATH:x

Ein weiteres which für Windows

Zuerst

cscript //H:CScript //S

ausführen, und dann folgendes VBScript:
http://pastie.org/907800

automatische m4a Konvertierung in gPodder

Eine kleine Zeile in einem Skript macht es möglich, m4a Dateien automatisch in mp3 zu konvertieren, wenn man den Player synchronisiert. Eventuell sollte man den ogg-Converter auskommentieren, wenn der Player ogg kann.
Siehe: https://bugs.gpodder.org/show_bug.cgi?id=585

Grip unter Ubuntu 9.10

Der AudioCD-Ripper „Grip“ wurde in Ubuntu 9.10 entfernt, da das Projekt seit Jahren nicht mehr weiterentwickelt wird. Allerdings verrichtet es seine Dienste nach wie vor exzellent. Ein .deb lässt sich hier herunterladen: http://ppa.launchpad.net/kirkland/ppa/ubuntu/pool/main/g/grip/

dbus statt gnome-power-cmd

Seit Ubuntu 9.10 funktioniert

gnome-power-cmd

nicht mehr. Stattdessen kann man aber den folgenden knackigen Befehl benutzen:

dbus-send --print-reply --system --dest=org.freedesktop.DeviceKit.Power /org/freedesktop/DeviceKit/Power org.freedesktop.DeviceKit.Power.Hibernate

Problem dabei: Der Bildschirm wird nicht gesperrt. Dazu sollte es aber auch ein Kommando geben, dass man gleichzeitig ausführen kann.

„Ubuntu Firefox Modifications“/ubufox macht Probleme mit TabMixPlus etc.

Installiert man einige Addons in Firefox wie z.B. „Tab Mix Plus“ und „Personal Menu“ während „Ubuntu Firefox Modifications“ aktiviert sind, so bekommt man eventuell (bei mir: ziemlich zuverlässig) Probleme mit veränderten Toolbars etc., da sie in den Standardzustand zurückgestellt werden.
Einfach das Addon deaktivieren – einen erkennbaren Nutzen habe ich bisher ohnehin nicht festgestellt.

Alle versteckten Unterordner außer . und .. matchen

In der Bash beispielsweise so:

$ du -hsx .[^.]*
16K	.adobe
17M	.anki
16K	.aria2
4,0K	.asoundrc
[...]

robots.txt bei wget ignorieren

Will man wget dazu veranlassen, die robots.txt zu ignorieren, muss man den Parameter „-e robots=off“ verwenden.
Beachte: Dieser muss direkt vor der URL stehen.

wget -m -e robots=off http://www.url.tld

FAT32 Label ändern

Label eines FAT32 Dateisystems anzeigen:

$ sudo mlabel -i /dev/sdc1 -s ::

Label eines FAT32 Dateisystems ändern:

$ sudo mlabel -i /dev/sdc1 ::neuerName

Alles in Oracle löschen

Möchte man alle Objekte seines Users in Oracle löschen, so kann man sich eine Liste von Statements erzeugen lassen, die man ausführen kann um dies zu bewerkstelligen:

select 'drop '||object_type||' '|| object_name||  DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';') from user_objects

look-around assertion bei RegExp

Beispiel: Ich habe einen String „Katze.spielt.mit.Ball.avi“ und will diesen in „Katze spielt mit Ball.avi“ umwandeln. Dann ginge das (am Beispiel von „rename“) so:

rename -vn 's/.(?!avi)/ /g' *.avi

+x Recht eines Verzeichnisses

Das +x Recht bei einem Verzeichnis gestattet/verbietet es unter Unix, dass man das Verzeichnis betreten kann.
Was mir neu war, ist, dass dies quasi rekursiv wirkt: Hat man eine Verzeichnisstruktur /foo/bar/baz/, in der außer ‚bar‘ alle Verzeichnisse das +x Recht haben, kann man trotzdem nicht in ‚baz‘ wechseln, da auch ‚bar‘ geprüft wird.

einfacher Logger in C#

Hier ein einfacher Logger (im Grunde nur ein Wrapper um Console.Write()) in C#, den man bei Bedarf an und abschalten kann.

		public const bool doLog = true;
		
		public static void Log(string str, params object[] objs)
		{
			if (doLog)
			{
				Console.Write(str, objs);
			}
		}
		
		public static void LogLine(string str, params object[] objs)
		{
			Log(str+"n", objs);
		}

Für komplexere Szenarien sind dann natürlich professionelle Logger wie Log4Net zu empfehlen.

Dateien schematisch umbenennen

Kürzlich hat mich ein offensichtlicher Raubkopierer gefragt, wie man eine Reihe von Dateien im Format „American.Dad.S03E01.The.Vacation.Goo.German.FS.dTV.XviD.avi“ so umbenennen kann, dass „American Dad – S03E01.avi“ dabei rauskommt.
Eine Lösung wäre z.B.

rename -vn 's/American.Dad.(S..E..)..*/American Dad - $1.avi/' *.avi

sshfs mit Key

sshfs kann man zwar nicht direkt einen Key übergeben, aber über einen kleinen Trick geht es dennoch:

sshfs user@host:/pfad/ /media/mountpoint -o ssh_command='ssh -i /pfad/zum/key'

UUID einer Partition herausfinden

Bei Grub oder in der fstab kann man statt eines Blockdevices auch die UUID einer Partition angeben. Und die bekommt man wie folgt:

blkid /dev/sda7

sqlplus unter Linux

Um SQL*Plus unter Linux zu benutzen, müssen unter http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html (Logindaten gibts bei BugMeNot.com) die Pakete „Basic“ und „SQL*Plus“ heruntergeladen und entpackt werden.
Anschließend muss das Paket „libaio1“ via Paketverwaltung installiert werden.
Mit

LD_LIBRARY_PATH=. ./sqlplus username/password@193.196.84.156:1521/widb1

kann man sich nun auf den Server (hier: Oracle-Server der Fakultät WI an der HsKA) verbinden.

Seamless RDP mit Linux und Windows

Den Seamless-Mode kennt man aus Virtual Box: Der Desktop wird nicht gezeichnet, sondern nur die Fenster. Nachteil hierbei ist, dass die Fenster keinen eigenen Eintrag in der Taskleiste der Linux-Umgebung bekommen.
Um dies zu realisieren, kann man Seamless RDP verwenden:

Im Windows-Host (dieser muss RDP können, was Home-Editionen im Zweifelsfall wohl nicht tun) muss folgendes eingestellt sein:
Systemsteuerung → Benutzerkonten → „Use the Welcome Screen“ sowie „Fast User Switching“ müssen aktiv sein.
System → Remote → hier kann man eingeschränkte Benutzer hinzufügen. Admins haben wohl immer Zugriff.

Nun sollte man per RDP zugreifen können:

rdesktop 192.168.178.24 -u rdptest -p geheim

Bei dieser Gelegenheit öffnet man den Regedit unter Windows und stellt die Anzeige der Desktopicons ab: Unter dem Registrypfad HKEY_CURRENT_USER\Softwar\eMicrosoft\Windows\CurrentVersion\Policies\Explorer muss ein DWORD-Eintrag angelegt werden, der „NoDesktop“ heißt und den Wert 1 besitzt.
Zusätzlich läd man sich http://www.cendio.com/seamlessrdp/seamlessrdp.zip herunter und entpackt es z.B. unter C:\seamlessrdp
Nun wieder abmelden (nicht nur „trennen“!).

Mit

rdesktop -A -s "c:\seamlessrdp\seamlessrdpshell.exe explorer" 192.168.178.24 -u rdptest -p geheim

kann man sich nun die Taskleiste auf den Desktop holen und Programme starten.

Vorteile:
· Copy & Paste geht
· Fenster werden vom Windowmanager verwaltet
· RDP Features können benutzt werden (bspw. Druckerumleitung)
· Es kann statt eines gesamtes Windowsdesktops auch nur eine einzelne Anwendung gestartet werden (explorer dann z.B. durch notepad ersetzen)

Probleme:
· Mindestens unter Ubuntu 9.04 und 9.10 ist derzeit das rdesktop-Paket kaputt. Es werden Fensterdekorationen angezeigt, obwohl das nicht sein sollte. (Bugreport und Workaround)
· Die Taskleiste zuckt mit dem Windows-Classic-Skin nervös. Besser Luna oder ein alternatives Theme verwenden.
· Fenster mit Fokus werden nicht immer ordentlich in den Vordergrund geholt (oft z.B. bei Kontextmenüs).
· Automatisches Ausblenden der Taskleiste lässt einen blauen Rand überstehen.
· RDP ist technisch eher mit VNC als mit X-Forwarding zu vergleichen. Das Zeichnen der Fenster ist wie bei VNC daher eher träge.

Tipps:
· Die Option -P von rdesktop kann die Fensterinhalte zwischenspeichern und verbessert die Performance evtl. erheblich.

openvpn bricht wegen fehlender Option ab

Eigentlich ein ziemlich dummer Fehler, warum mein VPN nie funktioniert hat: Auf dem Server war die Kompression eingeschaltet, auf dem Client dagegen nicht.
Ein Blick in /var/log/syslog hätte sogar gezeigt: „WARNING: ‚comp-lzo‘ is present in remote config but missing in local config, remote=’comp-lzo'“
Nach dem im NetworkManager die Kompression ebenfalls eingeschaltet wurde, funktioniert alles wunderbar :)

.bin mounten

Man kann zwar keine .bin-Images von CDs direkt mounten, aber mit etwas Glück in .iso konvertieren:

bchunk -v foo.bin foo.cue irgendeinNeuerName[/v]
Danach, kann man sie (mit Glück) mounten:
1mount -t iso9660 -o loop irgendeinNeuerName.iso /mnt/

anderen lokalen User auf das eigene XDISPLAY zugreifen lassen

Situation: Man ist mit User „foo“ eingeloggt und möchte mit einem anderen, lokalen User „bar“ ebenfalls X-Clients starten.

foo@hostname:~$ xhost +si:localuser:bar
foo@hostname:~$ su - bar
bar@hostname:~$ XDISPLAY=:0.0 xcalc

mehrere Leerzeichen hintereinander durch eins ersetzen

cat foo1 | sed -r 's/ +/ /g' > foo2

Wichtig ist dabei die Option -r

DBDesigner Fork

Will man den DBDesigner Fork unter Linux mittels dem Skript startdbd_using_kernel2.6 starten, so wirft er einem womöglich diese Fehlermeldung entgegen: „./DBDesignerFork: error while loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory“
Hier hilft es, den Teil „LD_ASSUME_KERNEL=2.4.1“ aus dem Skript zu entfernen.

Debug-Modus bei Visual Studio Express

Wer sich schon mal gefragt hat, wie man den Debug-Build bei Visual Studio Express aktivieren kann:
Extras → Optionen → [x] Alle Einstellungen anzeigen → Projekte und Projektmappen → Allgemein → [x] Erweiterte Buildkonfiguration anzeigen

ISO-8859-15 nach UTF-8

Kleines, aber feines Tool, um eine Datei nach UTF-8 zu konvertieren:

recode utf-8 file.txt

Und dabei braucht es nicht einmal die Angabe des Ausgangszeichensatzes (wie es bei iconv der Fall ist)

rsync und Leerzeichen im Pfad

Aus der manpage:

If you need to transfer a filename that contains whitespace, you can either specify the –protect-args (-s) option, or you’ll need to escape the whitespace in a way that the remote shell will understand. For instance:

rsync -av host:'file name with spaces' /dest

doppelte @ in Message-ID entfernen

Ich hab mal ein kleines Perl-Script geschrieben, welches überprüft, ob eine Message-ID mehr als ein @ hat (was illegal wäre). Wenn dem so ist, wird die Message-ID umgeschrieben (ja, das ist böse) und die originale als X-Original-Message-ID gesichert.

use strict;
use warnings;

my $header = 1;
while (my $zeile = <>)
{
  if ($zeile =~ /^$/)
  { 
    $header = 0;
  }

  if ($header == 1)
  {
    while($zeile =~ m/^Message-ID: .*@.*@.*/)
    {
      print "X-Original-".$zeile;
      $zeile =~ s/@/__MULTI_AT__/;
    }
  }

  print $zeile;
}

Das Skript basiert auf dem standardmäßigen Input-Output Prinzip: Etwas wird per stdin ‚rein-gepiped‘ und wird per stdout ausgegeben.

inews -h

Möchte man „inews“ benutzen, so stößt man evtl. auf ein paar Fallstricke:
· inews: required Subject header is missing or empty
Wurde eine Nachricht mit komplettem Header mitgegeben? Dann muss „inews -h“ benutzt werden.

· inews: warning: cannot connect to server
Hier ist irgendwo ein falscher Server eingetragen. Entweder in der inn.conf unter „server“ oder in der Umgebungsvariable „NNTPSERVER“

· inews: cannot send article to server: 441 Can’t set system „NNTP-Posting-Host“ header
Hier wurde in der Nachricht ein Header mitgegeben, der nicht erlaubt ist (weil er vom Server selbst gesetzt wird)

Auf http://www.faqs.org/faqs/inn-faq/part4/section-10.html finden sich noch weitere Hinweise.

Mail2News Gateway mit Inn

Ich möchte hier kurz beschreiben, wie man Mails an eine bestimmte Adresse in eine Newsgroup einspeisen kann. Ich gehe dabei davon aus, dass der Newsserver Inn ist, ein MTA wie Postfix Mails über SMTP annimmt (es geht vermutlich auch mit Fetchmail mit nachgeschaltetem Procmail) und unser Server über foobar.dyndns.org ansprechbar ist.

Zuerst muss eine neue Newsgroup angelegt werden

su - news
/usr/lib/news/bin/ctlinnd newgroup mailinglists.kernel

Nun legen wir als root einen Alias in „/etc/aliases“ an, an den Mails geschickt werden können:

ml_kernel: |" /usr/lib/news/bin/mailpost mailinglists.kernel "

Anschließend ist

newaliases

auszuführen.
Die Zeile in /etc/aliases bewirkt, dass Mails an ml_kernel@foobar.dyndns.org an das Kommando „/usr/lib/news/bin/mailpost mailinglists.kernel“ gepipt werden. mailpost bereitet die Mail auf, leitet es an „inews“ weiter, welches die News an Inn schickt.

Da inews und mailpost als nobody ausgeführt werden, muss sichergestellt werden, dass sie Lesezugriff auf /etc/news/inn.conf haben. Bei mir war es notwendig, „chmod +x /etc/news“ auszuführen.

Nun sollten Mails an ml_kernel@foobar.dyndns.org in die Newsgroup mailinglists.kernel gepostet werden.

Sollten Fehler auftauchen, ist es meist sehr sehr mühsam, diese zu finden. Ein Blick in /var/log/mail ist immer sinnvoll, Logs in /var/log/news/ bergen selten nützliche Infos. Nervig ist, dass Fehlermeldungen/Ausgaben von mailpost oft nirgends angezeigt werden. Hier kann folgende Erweiterung in der aliases helfen:

ml_kernel: |" /usr/lib/news/bin/mailpost mailinglists.kernel >> /tmp/mail2news.log 2>> /tmp/mail2news.log"

mailpost Fehler auf Grund falscher Berechtigung

Wenn man mit mailpost herumgespielt hat (als User ungleich nobody), so wird man später das Problem haben, das nobody auf eine Datenbank zugreifen will, aber keine Rechte dazu hat:

Command died with status 13: " /usr/lib/news/bin/mailpost mailinglists.xyz ". Command output: ndbm store returned -1, errno 13, key "a3d939dac03482b5d9e8f5fc39bba027.squirrel@mein.subbie.net" at /usr/lib/news/bin/mailpost line 370, <STDIN> line 83.

Das einfachste ist, diese Datenbanken zu löschen (sie enthalten die Message-IDs von bisher geposteten Mails)

rm /var/spool/news/tmp/mailpost-msgid.dir /var/spool/news/tmp/mailpost-msgid.pag

Ein „chown“ sollte auch gehen, und wäre wohl der saubere Weg.

Allgemeiner Tipp: Arbeitet am besten gleich als nobody („su – nobody“), wenn ihr solche Sachen testen wollt.

End-of-File eingeben

Manchmal erwartet ein Programm eine Eingabe (so z.B. inews oder cat), um dieser weiter zu verarbeiten. Bei mehrzeiliger Eingabe stellt sich nun die Frage, wie man dem Programm klar macht, dass der Text nun zu Ende ist.
Die Lösung ist, dass man das Kontrollzeichen End-of-File (EOF) schickt. Dies kann man meist mit STRG+D bewerkstelligen.

rsync über ssh mit alternativem Port

Will man rsync über SSH benutzen, und dabei einen alternativen Port 12345 benutzen, so kann man den Parameter -e benutzen.
Dieser gibt an, welches Programm als remote shell benutzt werden soll.

rsync -e 'ssh -p 12345' source user@host:/path/

ADO.NET CSV auf deutschen Systemen

Wer sich schon mal mit CSV-Import unter C# herumgeschlagen hat, wird sich auf einem deutschen System vielleicht über folgende Meldung gefreut haben:
„Unbehandelte Ausnahme: System.Data.OleDb.OleDbException: Das Feldtrennzeichen für die angegebene Textdatei entspricht dem Dezimaltrennzeichen oder Texttrennzeichen.“
Hierbei handelt es sich um einen ganz großen Wurf von Microsoft: Das Trennzeichen (also das Komma) darf nicht zugleich das Trennzeichen für Fließpunktzahlen (also das Komma in Deutschland) sein. (Das kann doch nicht wirklich deren Ernst sein? Wozu gibt es Feldbegrenzer?)

Jedenfalls hilft es hierbei, das Kommazeichen für Bruchzahlen (1,23) auf einen Punkt zu setzen (1.23). Dies geschieht über die schema.ini

[test.csv]
Format=Delimited(,)
DecimalSymbol=.

Die schema.ini ist dann noch mal ein ganz eigener Spaß… (bitte selber googlen, falls ihr nichts mit schema.ini anfangen könnt)

farbiges diff in SVN mit colordiff

Sein „svn diff“ einzufärben ist denkbar leicht:

Zuerst wird colordiff installiert und dann in „~/.subversion/config“ noch folgender Eintrag gemacht:

diff-cmd = /usr/bin/colordiff

Alle MyISAM Tabellen umwandeln

Wenn man alle Tabellen umwandeln will, ist es vermutlich ziemlich ätzend, jede einzeln umzuwandeln. Mit diesem Query kann man sich eine Reihe von SQL-Queries erstellen lassen, die alle Tabellen in ‚datenbankname‘ umwandelt.

SELECT CONCAT('ALTER TABLE ',table_schema ,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE table_type='BASE TABLE' AND engine != 'InnoDB'
  AND table_schema = 'datenbankname'

Mit etwas Kreativität lässt sich dieses Schema auch auf andere Tabellenänderungen anwenden.

MyISAM in InnoDB umwandeln

Wer sich mal den Kopf zerbrochen hat, wie man eine MyISAM Tabelle in MySQL in eine InnoDB Tabelle umwandelt:

ALTER TABLE t1 ENGINE=InnoDB;

Alle Dateien mit bestimmter Endung einer Website runterladen

Hat man eine Seite, auf der z.B. eine Reihe MP3s verlinkt sind, kann man mit folgendem Befehl alle runterladen:

wget -O - 'http://www.somwhere.de/blabla.php' | grep -o -E 'http://[^"]*.(mp3)' | wget -i -

Der geht allerdings nur, wenn die Verlinkungen absolut (d.h. nicht relativ) sind.

Wie ich gerade merke, erfüllt diese Zeile aber das gleiche (und sollte zudem auch bei relativen Verlinkungen funktionieren):

wget --span-hosts -r -l1 --no-parent -erobots=off -A.mp3 'http://www.somwhere.de/blabla.php'

Wichtig ist hierbei das –span-host, welches auch das Herunterladen von anderen Domains als www.somewhere.de erlaubt.

Kompilieren mit apt

Wer sich schon immer mal gefragt hat, was deb-src Zeilen sind, und was man mit ihnen machen kann – hier die Antwort:
Wenn man die deb-src Zeilen aktiviert hat, kann man sich mit den Befehlen die Kompilations-Abhängigkeiten herunterladen, anschließend den eigentlichen Source und ihn automatisch kompilieren.

sudo apt-get build-dep banshee
sudo apt-get --build source banshee

In /usr/src/ sollte sich nun entsprechendes befinden.

VirtualBox: Nachträglich seriellen Port installieren

Will man in einer VirtualBox mit XP-Guest im Nachhinein einen COM1 Port installieren, so wundert man sich vielleicht, dass dieser nicht im Gerätemanager auftaucht.
Diese muss man erst über „Systemsteuerung->Hardware“ hinzufügen („Ja, Hardware wurde bereits angeschlossen“ -> „Neue Hardware hinzufügen“ -> Suchen lassen und hoffen).
Danach müsste der COM-Port im Gerätemanager erscheinen.

EPK Shapes/Symbole für Dia

Ereignisgesteuerte Prozessketten (kurz: EPK) lassen sich traditionell mit ARIS oder MS Visio modellieren. Beim freien Dia sind zwar keine Shapes mitgeliefert, können aber unter http://www.hawlisch.de/devel/dia/index.html heruntergeladen werden.

Grub mag keine großen Inodes

Heute habe ich eine ext3 angelegt, und mittels rsync mein Linux gespiegelt. Dann wollte ich noch Grub einrichten, was allerdings nicht funktionierte. Entweder kam ein „Error 2: Bad file or directory type“ (o.ä.) oder er fand /boot/grub/stage1 nicht.
Die Ursache des Problems: Das ext3 Dateisystem wurde mit einer Inode-Größe von 256 angelegt, wobei verschiedene (ältere? ungepatchte? Versionen 128 wollen.
Abhilfe des Problems: Neue Grub-Version installieren. (Versucht erst gar nicht, die Inodegröße zu verkleinern – man kann sie nur vergrößern)

Oracle an IWI HsKA

Wer von außen auf den Oracle Server zugreifen will, muss sich zuerst in das VPN einwählen.
Danach muss als Verbindungstyp ‚Basic‘ mit folgenden Einstellungen benutzt werden.
Hostname: 193.196.84.156
Port: 1521
Servicename: widb1