Zadanie #3 - pop3 z MIME

Napisz w dowolnym, wybranym przez siebie języku programowania różnym od "C" program uruchamiany poleceniem postaci:

pop3cli user pop3.server 

gdzie:
Skrypt powinien:
W wariancie na ocenę 3.0:
W wariancie na ocenę 4.0:
W wariancie na ocenę 5.0:

MIME (Multipurpose Internet Mail Extensions)

MIME rozszerza możliwości standarowych protokołów pocztowych o zdolność do przenoszenia informacji nietekstowej. Jak wskazuje jego nazwa (w tłumaczeniu: wielozadaniowe rozszerzenia poczty internetowej), MIME jest rozszerzeniem istniejących systemów, a nie ich zamiennikiem.  Dla protokołu MIME ważne jest to, co użytkownik przesyła, a nie mechanizm dostarczania poczty. MIME nie zastępuje POP czy SMTP, rozszerza jedynie definicję „poczty" i klasę danych, jakie można bezpiecznie transferować z użyciem standardowych mechanizmów pocztowych.

NAGŁÓWEK WIADOMOŚCI MIME

Aby wiadomość mogła zostać rozpoznana jako zakodowana zgodnie ze standardem MIME, jej nagłówek musi zawierać dodatkowe pola, których nie używa się w klasycznej postaci nagłówka (opisanej w RFC 822). Poniżej zostaną opisane w kolejności, w jakiej zwyczajowo się je umieszcza.

POLE WERSJI MIME

Obecność tego pola jest najczęściej używana do rozpoznawania wiadomości kodowanych standardem MIME. Format pola w postaci ogólnej przedstawia się jak poniżej:

MIME-Version: <cyfra>.<cyfra>

UWAGA! Pole wersji MIME może zawierać dodatkowy komentarz wygenerowany przez klienta poczty, który powinien zostać zignorowany po stronie odbiorczej. Komentarz jest umieszczany jako ostatni element pola i ujmowany jest w nawiasy okrągłe, np:

MIME-Version: 1.0 (Generated by Secret Mail Agent version 3.7)

POLE TYPU ZAWARTOŚCI

Pole typu zawartości używane jest do wskazania klientowi poczty zarówno użytego sposobu kodowania wiadomości, jak i ewentualnie sposobu postępowania z odebraną wiadomością. Postać ogólna pola przedstawia się jak poniżej:

Content-Type: <typ>/<podtyp>; [<parametr>; [ <parametr>; ] ... ]

gdzie <typ> może być jednym z poniższych słów

application
audio
image
message
multipart
text
video

i służy do zgrubnego opisania zawartości wiadomości pocztowej. Dokładny opis typu zawartości podawany jest w elemencie <podtyp>, co najłatwiej jest chyba pokazać na kilku przykładach:

Content-Type: text/plain; charset="iso-8859-1"

wiadomość zawiera czysty (plain) tekst (text) zapisany w standardzie ISO 8859-1

Content-Type: image/jpeg; name="Cennik.jpg"

wiadomość zawiera obrazek (image) zapisany w standardzie jpeg, oryginalnie przechowywany w pliku o nazwie "Cennik.jpg"

Dla celów rozwiązania naszego dzisiejszego zadania szczególnie dla nas interesującym jest typ zawartości określanym poniższym polem:

Content-Type: multipart/mixed; boundary="ciag_znakow_uzywany_jako_znacznik"

wiadomość zawiera kilka rozłącznych części np. zasadniczą treść wiadomości oraz pewną liczbę załączników. Tekst będący wartością parametru 'boundary' będzie wykorzystywany jako znacznik rozdzielający każdy ze składników wiadomości.

Kilku słów komentarza wymaga dobór ciągu znaków używanych jako znacznik. Należy go dobrać tak, aby mieć pewność, że nie wystąpi nigdzie w treści wiadomości pocztowej. Często stosowaną sztuczką jest użycie wewnątrz takiego ciągu pary znaków =_ (równa-się podkreślenie), która z całą pewnością nie wystąpi ani w tekście zakodowanym jako quoted-printable (opisane w dalszej części), ani wewnątrz kodu base64. Dodatkowo należy wspomnieć, iż taki ciąg znaków MUSI zostać poprzedzony dwuznakiem -- (minus minus) w momencie, w którym zostanie użyty jak faktyczny ogranicznik. Jest to wybieg, który pozwala zachować zgodność z kilkoma starszymi RFC oraz powoduje, że wzorzec ogranicznika jest istotnie różny od samego ogranicznika, a tym samym nie może być z nim pomylony. Podsumowując: jeśli użyto pola postaci:

Content-Type: multipart/mixed;  boundary="gc0p4Jq0M2Yt08jU534c0p"

to wewnątrz wiadomości należy używać ogranicznika postaci:

--gc0p4Jq0M2Yt08jU534c0p

Dodatkowo, ostatni ogranicznik, kończący całą wiadomość, powinien zostać wydłużony o dwa myślniki, czyli powinien przybrać postać poniższą:

--gc0p4Jq0M2Yt08jU534c0p--

Uwaga ogólna: jeśli pewne pole wraz z parametrami ma długość większą niż dopuszczalna w wiadomości pocztowej, należy ją przełamać bezpośrednio po znaku ';' a linię następną (kontynuującą) należy rozpocząć znakiem HT lub spacją.

PODNAGŁÓWKI

Wiadomość określona jako wieloczęściowa powinna na początku każdej części zawierać podnagłówek opisujący jej zawartość. Interesować nas będą dwa typy podnagłówków - poprzedzające zasadniczą treść listu oraz poprzedzające załączniki.

PODNAGŁÓWEK PRZED TREŚCIĄ LISTU

Zakładamy dla naszych potrzeb, że podnagłówek taki ma następują postać:

Content-Type: text/plain; charset="iso-8859-2"
Content-Transfer-Encoding: quoted-printable

gdzie pole Content-Type jest dla klienta POP3 wskazówką, w jaki sposób traktować znaki narodowe, a pole Content-Transfer-Encoding informuje, w jaki sposób traktuje się znaki o kodach większych od 127.

Kilka słów wyjaśnienia wymaga omówienie kodowania "quoted-printable". Umożliwia ono przenoszenie znaków ASCII o kodach większych od 127 bez konieczności przekodowywania całego tekstu. Standard kodowania jest w miarę prosty i daje się opisać następującymi regułami:

Reguła #1: każdy znak wiadomości z wyjątkiem znaków kończących linię może być przedstawiony jako

=XX

gdzie XX to cytry szesnastkowe reprezentujące kod takiego znaku. Oznacza to w konsekwencji, że jedynym dopuszczalnym sposobem reprezentowania znaku = (równa się) jest przedstawienie go jako:

=3D

Reguła #2: Znaki o dziesiętnych kodach ASCII zawartych w przedziałach <33..60> oraz <62..127> mogą być przedstawiane literalnie.

Reguła #3. Znaki o dziesiętnych kodach ASCII 9 (HT) i 32 (SPACJA) przedstawione literalnie nie mogą być ostatnimi znakami w linii.

Reguła #4. Znaki przejścia do nowej linii (CR LF) przedstawiane są literalnie.

Reguła #5. Znak '=' umieszczony literalnie jako ostatni widoczny znak linii oznacza, że linia, w której się znajduje oraz linia następna stanowiły w oryginalnej wiadomości jedną linię, która została przełamana wyłącznie ze względu na ograniczenie szerokości wiadomości pocztowej.

PODNAGŁÓWEK PRZED ZAŁĄCZNIKIEM

Zakładamy dla naszych potrzeb, że podnagłówek taki ma następują postać:

Content-Type: image/jpeg; name="Cennik.jpg"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Cennik.jpg"

gdzie pole Content-Type ma znaczenie takie, jak opisano wcześniej, pole Content-Transfer-Encoding informuje, w jaki sposób zakodowano informację binarną, a pole Content-Disposition identyfikuje tę część wiadomości jako załącznik.

Zakładamy ponadto, że dla celów przesyłania informacji binarnych używamy wyłącznie znanego nam już kodowania base64.

PRZYKŁADOWA WIADOMOŚĆ POCZTOWA ZAKODOWANA STANDARDEM MIME

Poniżej znajduje się prawie kompletna wiadomość pocztowa zawierająca treść oraz trzy krótkie załączniki. Zwróć uwagą na fakt, iż klient SMTP w miejscu, w którym w standardowo kodowanym liście zaczyna się treść, umieścił informację o zastosowaniu kodowania MIME, co pozwala zorientować się w sytuacji użytkownikowi, którego klient POP3 nie jest w stanie prawidłowo obsłużyć takiego formatu.
Date: Sun, 05 Oct 2011 21:30:30 +0100
From: SW <swernikowski@wi.zut.edu.pl>
To: swernikowski@wi.zut.edu.pl
Subject: WIADOMOSC MIME
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="------------060305090202000204090500"

This is a multi-part message in MIME format.
--------------060305090202000204090500
Content-Type: text/plain; charset=ISO-8859-2;
Content-Transfer-Encoding: quoted-printable

To jest przyk=B3ad wiadomo=B6ci zakodowanej wg. standardu MIME.
Niewiele jest tu tre=B6ci i tak ma być.

--------------060305090202000204090500
Content-Type: application/octet-stream;
name="Attach3.bin"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="Attach3.bin"

AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1
Njc4OTo7PD0+Pw==
--------------060305090202000204090500
Content-Type: application/octet-stream;
name="Attach2.bin"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="Attach2.bin"

AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1
Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr
bG1ub3BxcnN0dXZ3eHl6e3x9fn8=
--------------060305090202000204090500
Content-Type: application/octet-stream;
name="Attach1.bin"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="Attach1.bin"

AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1
Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr
bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch
oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX
2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==
--------------060305090202000204090500--


Powyższy dokument zawiera tylko najważniejsze elementy standardu MIME. Pełny opis protokułu zawiera RFC 1521 dostępne np. pod adresem:
http://www.ietf.org/rfc/rfc1521.txt?number=1521

Opis konwencji kodowania znaków diakrytycznych w nazwach plików opisuje RFC 1522, dostępne ponizej:
http://www.ietf.org/rfc/rfc1522.txt?number=1522