PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Das POP3 Protokoll im Detail betrachtet

without comments

Nachdem ich bereits das IMAP Protokoll und auch das SMTP Protokoll unter die Lupe genommen habe, möchte ich heute das POP3 Protokoll untersuchen und zeigen welche Befehle es gibt und wie man damit E-Mails von einem Mail-Server lesen kann. POP3 ist genauso wie IMAP ein Protokoll zum Abholen von E-Mails mit einem Mailclient wie zum Beispiel Outlook, Thunderbird etc.

Zuerst müssen wir uns zum Server verbinden, das geht entweder unverschlüsselt oder verschlüsselt mittels TLS oder SSL. Hier die verschiedenen Wege:

telnet pop3.phpgangsta.de 110
Trying 85.214.28.26...
Connected to pop3.phpgangsta.de.
Escape character is '^]'.
+OK Dovecot ready.

Verschlüsselt mit TLS sieht das so aus:

openssl s_client -crlf -connect pop3.phpgangsta.de:110 -starttls pop3
CONNECTED(00000003)
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=18:self signed certificate
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=10:certificate has expired
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
---
Certificate chain
0 s:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
i:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDQDCCAqmgAwIBAgIJAPqlHcMGI8LLMA0GCSqGSIb3DQEBBQUAMHQxHDAaBgNV
BAoTE0RvdmVjb3QgbWFpbCBzZXJ2ZXIxEjAQBgNVBAsTCWgxNDQwNjgyLjEiMCAG
A1UEAxMZaDE0NDA2ODIuc3RyYXRvc2VydmVyLm5ldDEcMBoGCSqGSIb3DQEJARYN

...

---
+OK Dovecot ready.

Und schliesslich verschlüsselt mit SSL über den Port 995:

openssl s_client -connect pop3.phpgangsta.de:995
CONNECTED(00000003)
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=18:self signed certificate
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=10:certificate has expired
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
---
Certificate chain
0 s:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
i:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDQDCCAqmgAwIBAgIJAPqlHcMGI8LLMA0GCSqGSIb3DQEBBQUAMHQxHDAaBgNV
BAoTE0RvdmVjb3QgbWFpbCBzZXJ2ZXIxEjAQBgNVBAsTCWgxNDQwNjgyLjEiMCAG
A1UEAxMZaDE0NDA2ODIuc3RyYXRvc2VydmVyLm5ldDEcMBoGCSqGSIb3DQEJARYN

...

---
+OK Dovecot ready.

Gut, die Verbindung steht, nun müssen wir uns authentifizieren. Dazu gibt es verschiedene Möglichkeiten, hier die einfachste:

USER xxxx@phpgangsta.de
+OK
PASS SicheresPasswort
+OK Logged in.

Der Loginname und das Passwort werden einzeln um im Klartext an den Server geschickt. Solange TLS oder SSL bereits aktiviert sind ist das kein Sicherheitsproblem, sollte allerdings keine Verschlüsselung aktiviert sein sollte man für die Authentifizierung besser APOP nutzen (auch wenn das nicht 100% sicher ist):
http://de.wikipedia.org/wiki/APOP

+OK POP3 server ready <1896.697170952@phpgangsta.de>
APOP xxx@phpgangsta.de c4c9334bac560ecc979e58001b3e22fb
+OK Logged in.

Der zweite Parameter ist ein MD5-Hash, der aus dem Zeitstempel ( <process-ID.timestamp@hostname> ) und dem Klartextkennwort gebildet wird. Dies kann der Server dann überprüfen und den Login zulassen oder nicht.

Nach dem Login möchten wir wahrscheinlich eine Liste aller E-Mails haben. Eine vollständige Liste aller Nachrichtennummern und Größen gibt es mit dem Befehl

LIST
+OK 7 messages:
1 1737
2 2333
3 1984
4 1788
5 4094
6 2693
7 2279
.

Nur die Größe der 5. Nachricht fragt man so ab:

LIST 5
+OK 5 4094

Möchten wir nun eine E-Mail abrufen holen wir wie folgt die komplette 1. Nachricht:

RETR 1
+OK 1737 octets
Return-Path: <XXXX@domain.de>
Delivered-To: xxx@phpgangsta.de
Received: from localhost (h1440682.stratoserver.net [127.0.0.1])
by h1440682.stratoserver.net (Postfix) with ESMTP id 0EBBAEC9A8F
for <xxx@phpgangsta.de>; Sun, 29 Nov 2009 11:14:26 +0000 (UTC)
Message-ID: <4B125783.9050508@gmx.de>
Date: Sun, 29 Nov 2009 12:14:11 +0100
From: Michael Kliewe <XXXX@domain.de>
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
MIME-Version: 1.0
To: xxx@phpgangsta.de
Subject: test neues Konto
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

das sollte ankommen
.

Wir können auch nur die Header abfragen:

TOP 1 0
+OK
Return-Path: <XXXX@domain.de>
Delivered-To: xxx@phpgangsta.de
Received: from localhost (h1440682.stratoserver.net [127.0.0.1])
by h1440682.stratoserver.net (Postfix) with ESMTP id 0EBBAEC9A8F
for <xxx@phpgangsta.de>; Sun, 29 Nov 2009 11:14:26 +0000 (UTC)
Message-ID: <4B125783.9050508@gmx.de>
Date: Sun, 29 Nov 2009 12:14:11 +0100
From: Michael Kliewe <XXXX@domain.de>
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
MIME-Version: 1.0
To: xxx@phpgangsta.de
Subject: test neues Konto
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

.

Mit „TOP 1 10“ könnten wir uns die Header plus die ersten 10 Zeilen der E-Mail geben lassen.

Möchten wir eine E-Mail löschen (weil wir sie gelesen bzw. heruntergeladen haben) markieren wir sie zur Löschung:

DELE 1
+OK Marked to be deleted.

Fragen wir nun erneut die Liste aller vorhandenen E-Mails ab erhalten wir:

LIST
+OK 6 messages:
2 2333
3 1984
4 1788
5 4094
6 2693
7 2279
.

Die erste Nachricht fehlt (wir haben sie ja zum Löschen markiert), aber bemerkenswert ist dass die fortlaufende Nummerierung nicht wiederhergestellt wurde, es gibt nun also eine Lücke. Sobald man sich ausloggt wird die zum Löschen markierte E-Mail wirklich gelöscht. Wenn man das nicht möchte und sie wiedergestellen möchte hilft ein Reset der Markierungen:

RSET
+OK

Möchte man eine eindeutige Kennung herausfinden geht das mit dem UIDL Kommando:

UIDL 6
+OK 6 UID21-1259493142

Eine vollständige Liste alle UIDs erhält man mittels

UIDL
+OK
1 UID3-1259493142
2 UID4-1259493142
3 UID5-1259493142
4 UID7-1259493142
5 UID20-1259493142
6 UID21-1259493142
7 UID84-1259493142
.

Wenn die Verbindung aufrecht erhalten werden soll müssen wir etwas gegen den drohenden Timeout machen, wir senden periodisch ein NOOP um dem Server zu sagen dass wir noch da sind:

NOOP
+OK

Ein kurzer Befehl um den aktuellen Status anzeigen zu lassen:

STAT
+OK 7 16573

Damit könnte man beispielsweise schnell prüfen ob neue E-Mails dazugekommen sind usw.

Soll die Verbindung getrennt werden loggen wir uns aus:

QUIT
+OK Logging out, messages deleted.
Connection closed by foreign host.

Tja, das war es schon wieder, POP3 ist ziemlich einfach, es gibt keine Ordner oder Flags wie in IMAP, deshalb ist die Kommandoübersicht recht kurz. Bis auf einige Sonderfälle sollte immer IMAP verwendet werden, dann kann man mit Ordner und Flags arbeiten, Dank IMAP IDLE kommen E-Mails in Echtzeit an usw.

Written by Michael Kliewe

November 28th, 2011 at 9:53 am

Leave a Reply

You can add images to your comment by clicking here.