Monday, 8. March 2010
sed revisited
Der Eintrag kommt noch, versprochen. Für alle Ungeduldigen gibt es hier bereits eine Vorschau auf den 3. Teil (inklusive Teil 1 und 2).
Wednesday, 20. January 2010
VimPlugin: histwin.vim
Einen relativ kurzen Überblick gibt die Hilfe in :h undo-tree und :h usr_32
Daher habe ich jetzt mal angefangen ein Plugin histwin.vim zu schreiben, dass die Navigation zu den diversen Undo-Branches erleichtert. Der obligatorische Screenshot:
Wie ich finde, hat das Plugin mehrere Vorteile:
- Man sieht in welchem Undo-Branch man sich befindet (in obigen Beispiel grau hinterlegt, das ist leider noch etwas buggy)
- Man kann einen selektierten Branch mit der aktuell geladenen Version durchführen ("D" im Undo-Tree Window auf dem entsprechenden Branch drücken)
- Man kann bestimmte Branches taggen ("T" auf dem Branch drücken)
- Und als Spaßfeature habe ich mal einen Schnelldurchlauf durch alle Änderungen eingebaut, die vom Anfang bis zum gewählten Branch durchgeführt wurden ("R" auf dem Branch drücken). Man kann da also vim bei der Arbeit zusehen, wie es den Buffer bearbeitet.
Friday, 1. January 2010
Frohes Neues!
Hier noch ein paar Bilder vom Winter aus Thale. Ich habe lange nicht mehr so viel Schnee geräumt...
Wednesday, 11. November 2009
bash: eternal history
Das ist verwirrend und wenn man Pech hat, werden genau die Befehle überschrieben, die man unbedingt wieder benötigt hätte. Folgendermaßen bekommt man ein ewiges Logfile für die Bash:
HISTTIMEFORMAT='%F %T '
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ; }" 'echo $USER $(history 1) >> ~/.history'
Mit HISTTIMEFORMAT wird angegeben, wie das Datum für jeden Eintrag gespeichert werden soll. Danach gibt man an, dass jedesmal wenn der Prompt angezeigt wird, der vorige Befehl gespeichert werden soll (in diesem Fall: "Hänge den vorherigen Befehl an ~/.history an": echo $(history 1) >> ~/.history). $PROMPT_COMMAND gibt an, was ausgeführt werden soll, bevor der PROMPT angezeigt wird. Und ${PROMPT_COMMAND:+$PROMT_COMMAND} definiert, dass der nachfolgende Befehl an die eventuell bereits definierte Variable PROMPT_COMMAND angehängt werden soll.
Die History wird dann im Format
USER INDEX TIMESTAMP COMMMAND
gespeichert. Man kann natürlich noch zusätzliche Infos hinzufügen.
[UPDATE]
Der Vollständigkeit halber möchte ich noch ergänzen, wie man das auch lösen könnte:
~$ unset $HISTFILESIZE
~$ shopt -s histappend
~$ PROMPT_COMMAND='history -a'
Damit sollte auch ein ewiges Logfile geschrieben werden. HISTSIZE gibt die Anzahl der Einträge an, die die aktuelle bash-Session speichert, HISTFILESIZE die Anzahl der Einträge in der .bash_history. Mittels shopt -s histappend wird der bash mitgeteilt, dass die .bash_history nicht jedesmal überschrieben werden soll, sondern neue Einträge immer angehängt werden soll. Und mit PROMPT_COMMAND='history -a' wird eingestellt, dass jedesmal wenn ein Prompt angezeigt wird, der letzte Befehl in die Logdatei angehängt wird.
Das einzige Problem hierbei könnte sein, dass nach einer Zeit die history zu groß wird und damit die bash zuviel Speicher benötigt und unnötig lahm wird.
Wednesday, 4. November 2009
Vim: Text ausblenden, der das Suchmuster nicht enthält.
verschiedene Methoden, z.B. anhand der Syntax-Regeln, manueller Regeln, anhand der Einrückung oder anhand eines Ausdrucks.
Möchte man z.B. nur den Text einblenden lassen, der auf die Suche passt, kann man das so machen:
:set foldmethod=expr
:set foldexpr=getline(v:lnum)!~@/
Das Problem dabei ist nur, dass dieser Ausdruck nicht jedesmal neu
ausgewertet wird und daher für spätere Suchvorgänge nicht mehr passt.
Am einfachsten ist es daher diesen Ausdruck per Autocommand ausführen zu lassen:
au CursorHold * :set foldexpr=getline(v:lnum)!~@/
Dann wird dieser Audruck immer nach einer bestimmten Anzahl Sekunden Inaktivität aktiviert. Nach wieviel Sekunden hängt von der Einstellung updatetime ab:
set updatetime?
4000
hier also 4 Sekunden
Wednesday, 30. September 2009
mutt und Vim: Anhänge
Dabei geht es auch anders. Ein eher weniger bekanntes Feature von mutt erlaubt es nämlich auch Dateien anzuhängen, die über die Headerzeile Attach: Datei angegeben wurden. Nun kann man bereits beim Schreiben der Mail eine entsprechende Anweisung im Header-Kopf der E-Mail hinterlassen und mutt wird automatisch die gewünschte Datei anhängen. So habe ich mir zum Beispiel den Befehl :Attach definiert, der eine entsprechende Kopfzeile in die E-Mail schreibt:
\exe "normal magg}-" | call append(line('.'), 'Attach: <args>') | normal `a
(siehe auch diesen alten Artikel).
Leider verhindert dass immer noch nicht, dass man vergisst die Datei anzuhängen und man sich trotzdem zum Deppen macht. Daher habe ich mal eine kleine Funktion geschrieben, welche die Mail scannt und den Nutzer zum Anhängen der Dateien auffordert, wenn sie bestimmte Stichworte findet.
Gestern nun habe ich daraus ein Plugin (CheckAttach.vim) für Vim gemacht. Einfach das Plugin runterladen, in Vim öffenen und einlesen:
:so %
:q!
Dann wird das Plugin automatisch installiert.
Beim Schreiben von Mails sollte das Plugin dann automatisch aktiv sein. Mit :DisableCheckAttach kann man das Plugin einfach deaktivieren und mit :EnableCheckAttach einfach wieder aktivieren, wenn man es deaktiviert hatte. Eine kleine Hilfe ist auch vorhanden (:h CheckAttach.txt)
Wenn das Plugin aktiv ist, wird es beim Speichern immer überprüfen, ob die Worte Anhang oder angehängt (bzw. attachment und attach) vorhanden sind und falls es diese findet, wird es den Benutzer auffordern, die Dateien anzugeben. Es generiert dann die entsprechenden Header automatisch. Dabei erlaubt vim Autovervollständigen der Dateien und man kann auch die Shell-Muster * angeben, um mehrere Dateien anzuhängen. Temporär deaktivieren kann man den Check auch wenn man mit ! speichert, also z.B. :w! anstelle von :w.
Wichtig: Falls der Pfad bzw. der Dateiname Leerzeichen enthalten, werden diese mit einem '\' maskiert. In mutt vor Version 1.5.20 können diese Dateien aber nicht angehängt werden. Das ist leider ein Bug. Wenn man mutt vor Version 1.5.20 einsetzt, müssen die Dateien vorher umbenannt werden.
Wednesday, 29. July 2009
Auf Großwildsafari ;)
Tuesday, 28. July 2009
Mit mencoder für die PlayStation Portable kodieren
-oac lavc -lavcopts aglobal=1:vglobal=1:vcodec=libx264:acodec=libfaac:vbitrate=640:abitrate=128:\
coder=1:level=21 -lavfopts format=psp Input -o Output
Man kann das ganze auch als Profil unter ~/.mplayer/mencoder.conf speichern:
profile-desc="PSP H.264 encoding profile."
vf=hqdn3d,scale=480:272
af=lavcresample=48000
ofps=30000/1001
ovc=lavc=1
oac=lavc=1
lavcopts=aglobal=1:vglobal=1:vcodec=libx264:acodec=libfaac:vbitrate=640:abitrate=128:coder=1:level=21
of=lavf=1
lavfopts=format=psp
und dann mit mencoder -profile psp Input -o Output passend kodieren
Wednesday, 8. July 2009
Vim Plugin sudoedit.vim
Daher hab ich das Plugin sudoedit.vim geschrieben. Wenn mir sowas wieder passiert, einfach Datei bearbeiten und zum Schluß :SudoWrite eingeben und die Datei wird mittels sudo/su oder mithilfe eines anderen konfigurierbaren Tools geschrieben.
Monday, 6. July 2009
Vim Highlightmark.vim Plugin
Dabei gibt es mindestens noch 2 andere Implementierungen: showmarks.vim und showmarks.vim Ich hab das erst hinterher erfahren, nachdem ich mein eigenes Script geschrieben habe. Ich kenne nämlich keines davon, mein Script funktioniert für mich zufriedenstellend.
Fehler und Anmerkungen nehme ich natürlich gerne entgegen. Dabei fällt mir ein, ich könnte mal wieder häufiger über diesen Editor bloggen. Mal sehen...
Monday, 15. June 2009
Auf dem Sachsen-Anhalt Tag
Dort habe ich die folgende Entdeckung gemacht und konnte endlich mal wieder mit meiner Kamera ein paar schöne Fotos schießen. Es waren nämlich eine paar Leute einer Falknerei da, und die hatten ihre Vögel dabei und man konnte die Tiere sogar streicheln. Dabei gelangen mir u.a. diese Schnappschüße:
Der Rest war auch schön (wenn auch das Gedränge nervte) und endlich mal was los
Update: Mehr Bilder von den Greifvögeln (der Falkner sagte es wären Falken, aber auf fotocommunity verbesserte man mich zu Habicht bzw. ein Bussard) hier
Wednesday, 27. May 2009
SSHFS und globaler Namespace
Ich springe bei der Arbeit auf einer Menge von Kisten rum und bearbeite dabei eine Menge Files - nichts besonderes wenn man Systeme administriert bzw. Software entwickelt. In letzter Zeit nutze ich vermehrt SSHFS. Das ist sehr praktisch, da man so die Tools (z.B. svn, vim, ctags, ...) die man auf seiner Workstation konfiguriert und installiert hat nutzen kann sofern man netzwerktechnisch in der Lage ist, eine SSH-Verbindung aufzubauen.
Prinzipiell geht das so:
aptitude install sshfs mkdir /home/mschoechlin/mnt/256bit.org/ sshfs -o idmap=user mschoechlin@256bit.org:/ /home/mschoechlin/mnt/256bit.org/ cat /home/mschoechlin/mnt/256bit.org/etc/fstab
Mit dem Tool "afuse" geht das noch bequemer - nebenbei bekommt man einen globalen Filesystemnamespace:
aptitude install afuse sshfs mkdir ~/sshfs afuse -o mount_template="sshfs -o idmap=user %r:/ %m" -o unmount_template="fusermount -u -z %m" ~/sshfs/ cd ~/sshfs cat user@host/etc/fstab cat host/etc/fstab killall afuse
Sobald man also mit "cd" in das Verzeichnis "~/sshfs/<user>@<hostname>" wechselt springt der "afuse" Automounter an und mountet das System via "sshfs". Dabei wird die UserId, über welche man sich angemeldet hat, immer auf die lokale gemapped. Die Verwendung des SSH-Agent/SSH-Keys ist hier ganz nützlich - andernfalls poppt ein Passwortdialog auf.
Friday, 8. May 2009
Eine kleine Einführung in sed, Teil 2
Wie ich im ersten Teil bereits beschrieben habe, arbeitet man bei sed meist mit Mustern, die bestimmte Teile definieren, an denen Änderungen vorgenommen werden sollen. Diese Muster werden typischerweise durch reguläre Ausdrücke definiert. GNU Sed unterstützt dabei einfache reguläre Ausdrücke (basic regular expressions) bzw. mit dem Schalter -r erweiterte reguläre Ausdrücke (extended regular expressions, z.B. was egrep benutzt). Die wichtigsten Regeln mal kurz erklärt:
^ Anfang der Zeile
$ Ende der Zeile
. irgendein Zeichen
[...] irgendein Zeichen welches innerhalb der eckigen Klammer angegeben ist.
[a-z] passt auf alle Kleinbuchstaben des Alphabets, [abc] entweder auf
a oder auf b oder auf c
[^...] irgendein Zeichen welches nicht innerhalb der eckigen Klammer angegeben
ist. [^a-z] passt auf alle Zeichen, die keine Kleinbuchstaben sind.
\(\) Klammerung (bei erweiterten regulären Ausdrücken ohne Backslash, also ().
Damit kann man sich Ausdrücke merken und später auf sie referenzieren
mit den Variablen \1 bis \10 D.h. man kann auf maximal 10 verschiedene
Zeichenketten referenzieren, mehr geht nicht. Dabei zählt immer die
Reihenfolge der öffnenden Klammer.
(\(a\)b\1 passt auf "aba" aber nicht auf "abba")
* Ein sogenannter Quantifier. Der vorherige Ausdruck kann 0 bis beliebig
oft auftreten, dabei wird ein längerer passender Ausdruck bevorzugt
(sogenannte Greediness, "Gier").
a* passt also auf "", a, aa, aaa, und so weiter, bei einer Zeichenkette
von baah, wird es aber immer auf aa passen.
\? Der vorherige Ausdruck passt genau 0 der 1 Mal (erweiterte reguläre
Ausdrücke: ?)
\+ passt auf den vorherigen Ausdruck 1 mal oder mehr. Längere Treffer
werden dabei bevorzugt. (Bei erweiterten regulären Ausdrücken +).
\{n\} passt auf den vorherigen Ausdruck genau n-Mal. (erweiterte reguläre
Ausdrücke: {n})
\{n,\} passt auf den vorherigen Ausdruck n oder mehrmals. (erweiterte reguläre
Ausdrücke: {n,})
\{n,m\} passt auf den vorherigen Ausdruck n oder m Mal (m>n). Längere Treffer
werden bevorzugt. (erweiterte reguläre Ausdrücke: {n,m})
\{,m\} passt auf den vorherigen Ausdruck maximal m Mal. Längere Treffer werden
bevorzugt. (erweiterte reguläre Ausdrücke: {,m}).
\| Entweder der vorherige Ausdruck oder der nachfolgende Ausdruck.
(bei erweiterten regulären Ausdrücken |). a\|b passt auf a oder auf b.
\n passt auf einen Zeilenumbruch¹ (siehe auch Anmerkung).
\$ passt auf ein $-Zeichen (denn $ steht ja für das Ende der Zeile).
So kann man mit dem Backslash nachstehende Zeichen maskieren. \* passt
auf einen *, und so weiter...
Das ist soweit das Wichtigste zu den regulären Ausdrücken, die von Sed unterstüzt werden. Die Syntax ist nicht so schwer, man muß sich nur merken, welche der vielen Dialekte der regulären Ausdrücke sed beherrscht. Des weiteren unterstüzt sed Posix Character Classes, d.h. das Muster [[:lower:]] passt auf alle Kleinbuchstaben und [[:upper:]] auf alle Großbuchstaben. Außerdem beherrscht sed noch Patterns, die mit einem Backslash anfangen. '\w' passt zum Beispiel auf ein "Word"-Character, als Character-Klasse ausgedrückt: [A-Za-z0-9_], '\W' passt auf ein Non-Word-Character und somit der Umdrehung von '\w' (also [^a-zA-Z0-9_].). Weitere \-Muster werden unterstüzt, ich verweise dafür mal auf das Manual bzw. die Info-Seiten.
¹Des weiteren sollte man beachten, dass sed seinen Input zeilenorientiert liest. D.h. normalerweise wird ein Pattern mit einem '\n' für einen Zeilenumbruch nicht passen. Man kann darum arbeiten, aber man sollte das im Hinterkopf behalten, wenn man '\n' benutzt.
So fortgeschrittene Sachen wie "look-ahead", "look-behind", non-greedy Matches oder non-capturing Groups der Perl-kompatiblen regulären Ausdrücke beherrscht sed leider nicht. (Eine gute Übersicht über die vorhandenen Möglichkeiten gibt die Wikipedia.)
Diese Ausdrücke definieren nun, wo etwas gemacht wird. Wenn man die Zeilennummer weiß, kann man aber auch diese benutzen. Zusätzlich erlaubt es GNU Sed noch Schrittfolgen zu definieren. Also zum Beispiel von Zeile 1 ausgehend, jede zweite (also 1,3,5,7...). 1~2 passt genau auf dieses Muster, während 0~2 jede gerade Zeile ausgibt. Verallgemeinert gesagt x~y, wobei x die Startzeile angibt und y die Schrittfolge. $ als Zeilennummer passt dagegen immer auf die letzte Zeile.
Nun haben wir ganz kurz die Adressmöglichkeiten besprochen. Nun möchte man normalerweise auch was machen. Dafür versteht sed sogenannte Kommandos. Diese Kommandos verstehen normalerweise alle 2-Adressen (nämlich eine Start- und eine Ende-Adresse), eine Adresse
Nun haben wir ganz kurz die Adressmöglichkeiten besprochen. Nun möchte man normalerweise auch was machen. Dafür versteht sed sogenannte Kommandos. Diese Kommandos verstehen entweder keine Adressen (z.B. Sprungangaben und Kommentare), Eine oder keine Adressangaben oder 2 Adressen (nämlich Start- und Ende-Adresse).
Die folgenden Kommandos kennt dabei Gnu Sed:
'#' Kennzeichnet einen Kommentar
's/x/y/' ersetze x durch y
':' definiert eine Sprungmarke
'=' Gib die Zeilennummer aus.
'a\
Text' Hängt "Text" als neue Zeile an
'i\
Text' Fügt "Text" in die aktuelle Zeile ein
'c\
Text' Ersetze die aktuelle Zeile durch "Text"
q Beende
r foobar hängt den Inhalt der Datei foobar hinter die aktuelle Zeile ein.
R foobar Fügt eine Zeile der Datei foobar hinter die aktuelle Zeile ein.
b foobar springe zur Sprungmarke foobar
'p' Print (ausgeben des Treffers)
t foobar springe zur Sprungmarke foobar, wenn vorher das letzte s-Kommando
erfolgreich war
t foobar springe zur Sprungmarke foobar, wenn vorher das letzte s-Kommando
nicht erfolgreich war
d lösche aktuell eingelesene Zeile und fang von vorne an
n lese nächste Zeile ein
N lese nächste Zeile ein und hänge an die aktuelle Zeile an.
w foobar Schreibe aktuellen Inhalt in Datei foobar
W foobar Schreibe nur erste Zeile des aktuellen Inputs in Datei (später mehr dazu).
'y/a/b/' Ersetze a durch b (funktioniert so ähnlich wie tr).
Mit y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ werden alle
Kleinbuchstaben durch die Großbuchstaben ersetzt.
! Führe nachfolgendes Kommando für alle Zeilen außer der aktuellen aus.
(Negation)
Normalerweise liest Sed den Input (bis zum Zeilenende \n) in den sogenannten "Pattern Space" und führt die Kommandos im Pattern Space aus und gibt anschließend die Änderungen aus. Daneben gibt es noch einen extra Puffer, den sogenannten Hold Space. In ihm kann man Daten zwischenspeichern und später wieder verwenden. Dafür gibt es die folgenden Kommandos.
D Lösche bis zum ersten Zeilenumbruch im Pattern Space und fang von vorne
an
x Tausche die Inhalte des Pattern Spaces und Hold Spaces aus.
h Kopiere Pattern Space in den Hold Space Puffer
H Hänge Pattern Space an den Hold Space Puffer an
g Kopiere Hold Space Puffer in den Pattern Space
g Hänge Hold Space Puffer an den Pattern Space an
Der Aufbau eines Kommandos ist dabei folgender:
sed -n '3p' gibt Zeile 3 und nur Zeile 3 aus. sed -n '3,5p' gibt alles von Zeile 3 bis 5 aus (inklusive). (Normalerweise wird bei Sed der Input immer auch ausgegeben, mit -n unterdrückt man das und nur wenn man es explizit verlangt (Kommando p) wird etwas ausgegeben).
Das einfachste Kommando ist das '#' Allein für sich macht das gar nichts und gibt einfach alles aus:
sed '#' foobar
Der Fuchs ist rot und rot sind auch Äpfel.
Das gleiche erreicht man auch mit dem "Kommando" ; welches eigentlich verschiedene Kommandos trennt. In diesem Fall führt es ein "Null" Kommando aus und gibt daher alles aus, was es einliest:
sed ';' foobar
Der Fuchs ist rot und rot sind auch Äpfel.
Das verbreiteste Kommando ist sicherlich das s-Kommando. Damit kann man nach einem Muster suchen und dieses durch ein anderes Ersetzen.
Zum Beispiel ersetzt sed 's/rot/grün/' foobar die Zeichenfolge "rot" durch "grün" in der Datei foobar.
sed 's/rot/grün/' foobar
Der Fuchs ist grün und rot sind auch Äpfel.
Naja, aber eigentlich ist der Fuchs ja rot und Äpfel sind grün. Daher kann man dem s-Kommando noch zusätzliche Flags mitgeben. Das bekannteste Flag ist das 'g'. Damit werden alle gefundenen Muster ersetzt:
sed 's/rot/grün/g' foobar
Der Fuchs ist grün und grün sind auch Äpfel.
Man kann aber auch nur bestimmte Muster ersetzen, zum Beispiel nur das 2. Muster:
sed 's/rot/grün/2' foobar
Der Fuchs ist rot und grün sind auch Äpfel.
Wenn kein Flag angegeben wird, wird impliziert die 1 angenommen (also das erste gefundene Muster wird ersetzt).
Ein weiteres Flag ist das i. Hierbei wird das Muster case-insensitiv gesucht, d.h. Klein-/Großbuchstaben spielen keine Rolle. Es ist auch möglich mehrere Flags zu kombinieren:
sed 's/ROT/blau/ig' foobar
Der Fuchs ist blau und blau sind auch Äpfel.
Manchmal möchte man aber auch Pfadangaben ersetzen. Blöd nur, dass der Slash / normalerweise das Muster vom Ersetzungstext trennt. Möchte man nun z.B.
/usr/local/share/foobar durch /usr/share/foobar ersetzen, müßte man sowas nutzen:
sed 's/\/usr\/local\/share\/foobar/\/usr\/share\/foobar/g script
Daher erlaubt es sed, irgendeinen anderen Delimiter zu nutzen, z.B. die Pipe |:
sed 's|/usr/local/share/foobar|/usr/share/foobar|g script
oder den Unterstrich _
sed 's_/usr/local/share/foobar_/usr/share/foobar_g script
oder irgend ein anderes Zeichen, was nicht im Muster vorkommt.
Manchmal möchte man auch das gefundene Pattern im Ersetzungsteil wieder verwenden. Wenn man zum Beispiel eine Anweisung in einer Konfigurationsdatei auskommentieren möchte, die mit "foobar" anfängt kann man das so machen:
sed 's/^\(foobar\)/#\1/' config
#foobar wichtig!
Oder man benutzt einfach den Replacement Character &, der für das Muster steht, das gefunden wurde:
sed 's/^\(foobar\)/#&/' config
#foobar wichtig!
Vereinfachen kann man das noch so:
sed '/^foobar/s/^/#/' config
#foobar wichtig!
Hier benutzen wir den regulären Ausdruck /^foobar/ als Adresse und nur Zeilen, die auf dieses Muster passen, werden ersetzt. Vereinfacht ersetzen wir das Zeichen '^' (das für den Zeilenanfang steht) durch ein '#' und fügen somit eine Raute am Anfang der Zeile ein.
Man kann noch mehr mit regulären Ausdrücken machen. Zum Beispiel alle Großbuchstaben durch ihre Kleinbuchstaben ersetzen:
ls /home/ | sed 's/[[:lower:]]/\U&/g'
CB
CHRISBRA
FTP
Sed sucht nach der Posix-Klasse von Kleinbuchstaben und ersetzt diese durch die entsprechenden Großbuchstaben. Das \U steht für Uppercase und wandelt alle Zeichen in die passenden Großbuchstaben um. Man beachte die Nutzung von & um das gefundene Muster wiederzuverwenden. Ohne das Flag 'g' wäre übrigens nur der erste Buchstabe groß geschrieben worden. Das gleiche kann man übrigens mit dem Kommando y/ erreichen:
ls /home/ | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
CB
CHRISBRA
FTP
Das ist etwas umständlich, denn das y-Kommando scheint keine Characterklassen anzunehmen, sondern man muß explizit alle Zeichen hinschreiben.
Das war das Wichtigste zum Substitute Kommando. Der nächste Teil kommt bestimmt
Thursday, 7. May 2009
Regexes bei Informatica
Monday, 27. April 2009
Fetchmail SSL-Fingerprint erneuern
13589:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed:s3_clnt.c:951:
fetchmail: SSL connection failed.
fetchmail: socket error while fetching from ...@gmx.de@pop.gmx.net
fetchmail: Query status=2 (SOCKET)
Man muß dazu sagen, dass ich fetchmail mit der folgenden Konfiguration aufrufe:
user "user@gmx.de" password "passwort" is "user" ssl
sslproto tls1 sslcertpath /etc/ssl/certs sslfingerprint
"BA:03:AC:50:A9:A0:C7:AF:1E:79:3A:B7:C0:E7:19:5E" sslcertck keep
(Nein, das Passwort ist nicht passwort und die E-Mail Adresse ist auch nicht user@gmx.de
In dieser Konfiguration überprüft fetchmail den angegebenen SSL Fingerprint (Option sslfingerprint) gegen den Fingerprint des Zertifikats, dass der Server angibt und wenn der Fingerprint nicht stimmt, dann gibt es eben obige Fehlermeldung. Zusätzlich wird mit der Option sslcertck überprüft, ob das Zertifikat (direkt oder indirekt) vertrauenswürdig ist. GMX verwendet zum Beispiel ein Zertifikat das von Thawte ausgestellt ist. Wenn man das Paket ca-certificates installiert, bekommt man unter anderem das Thawte Root-Zertifikat installiert und das System betrachtet diese Zertifikate als vertrauenswürdig. Der generische, manuelle Weg diese Zertifikate zu erhalten ist für Thawte hier beschrieben.
Zurück zu der obigen Fehlermeldung. Die sieht verdächtig nach einem erneuerten Zertifikat aus. Glücklicherweise kann man das recht einfach prüfen und damit ich mir die passenden Optionen nicht jedesmal aus der Manpage raussuchen muß, hier die Schrittfolge in Kurzform:
notBefore=Apr 27 08:51:09 2009 GMT
notAfter=May 10 07:06:14 2010 GMT
MD5 Fingerprint=92:C8:49:13:3A:55:D6:57:37:5F:0F:12:83:39:CE:06
In Langform: Zunächst bauen wir uns eine verschlüsselte Verbindung zu pop.gmx.net auf. Da sieht man z.B. welches Zertifikat der Server dem Client präsentiert. Dieses Zertifikat kann man sich dann auch in Textform ausgeben lassen (openssl x509 -text
fetchmail: 6.3.9-rc2 fragt pop.gmx.net ab (Protokoll POP3) um Mo 27 Apr 2009 21:43:53 CEST: Abfrage gestartet
Versuche, mit 213.165.64.22/995 zu verbinden...verbunden.
fetchmail: Herausgeber-Organisation: Thawte Consulting cc
fetchmail: Herausgeber-CommonName: Thawte Premium Server CA
fetchmail: Server-CommonName: pop.gmx.net
fetchmail: pop.gmx.net-Schlüssel-Fingerabdruck: 92:C8:49:13:3A:55:D6:57:37:5F:0F:12:83:39:CE:06
fetchmail: pop.gmx.net-Fingerabdrücke stimmen überein.
fetchmail: POP3< +OK GMX POP3 StreamProxy ready
fetchmail: POP3> CAPA
fetchmail: POP3< +OK
fetchmail: POP3< STLS
....
Ach ja, und spätestens am 10. Mai 2010 wird es wieder ein neues Zertifikat geben.
