przejście do zawartości
Jan Kończak
Narzędzia użytkownika
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Ostatnie zmiany
Menadżer multimediów
Indeks
Jesteś tutaj:
start
»
sk2
»
mail
sk2:mail
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
=== Wyłączanie echo w terminalu === Możesz dowiedzieć się który terminal jest używany przez twoją powłokę wykonując: \\ ''echo $TTY'' W dowolnym momencie możesz z innego terminala wykonać komendę która spowoduje wyłączenie bądź włączenie wyświetlania wpisanych przez znaków: \\ ''stty -F %%/dev/pts/%%//8// -echo'' \\ ''stty -F %%/dev/pts/%%//8// echo'' Używając tej metody możesz (częściowo) uniknąć pokazywania na ekranie wpisywanego z klawiatury hasła. ===== Wstęp o wiadomościach e-mail ===== W trakcie przesyłania wiadomości e-mail między serwerami SMTP najpierw przesyłana jest są adresy z "koperty" (envelope), potem jej zawartość (contents). \\ Zawartość (contents) każdej wiadomość e-mail składa się z nagłówków (headers) i treści (body). <html> <pre style="margin-top:-1.2em; line-height: 1em"> <b>MAIL FROM:<</b>grey@cat.baz<b>></b> <span style="color:gray">\ envelope</span> <b>RCPT TO:<</b>john@example.com<b>></b> <span style="color:gray">/ ("koperta")</span> <b>DATA</b> <span style="color:navy">From: Greebo <grey@cat.baz> <span style="color:gray">\ \</span> To: John Q. Public <john@example.com> <span style="color:gray">| headers | contents</span> Date: Mon, 13 Jan 2025 03:00:00 +0100 <span style="color:gray">| (nagłówki) | ("zawartość")</span> Subject: Khhhhhhhhhhhhh <span style="color:gray">/ |</span> <span style="color:gray"> |</span> KhIIIIsss! <span style="color:gray">] body (treść) /</span> </span><b>.</b> </pre> </html> Zauważ że używany do dostarczenia wiadomości adres odbiorcy znajduje się na "kopercie". Adres docelowy który jest w nagłówkach w jej zawartości nie jest brany pod uwagę przy ustalaniu dokąd wiadomość ma zostać wysłana. \\ "Koperta" jest tworzona tylko na czas wymiany zawartości między serwerami i użytkownicy poczty nie widzą adresów które tam były podane (<small>choć serwer odbierający może przepisać adres z //rcpt to// do nagłówka //Received//</small>). === Składnia nagłówków === Linie muszą się kończyć przez ''\r\n'', lista nagłówków przez ''\r\n\r\n''. <html><div style="margin-left:0.5em;padding-left:0.5em;border-left:1px gray solid;display:block; margin-bottom: 0"></html> Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF. [[https://datatracker.ietf.org/doc/html/rfc5322#section-2.1.1#section-2.3.1|[RFC dla formatu wiadomości e-mail]]] <html></div></html> Linie nagłówków można w razie potrzeby łamać na białych znakach, zostawiając białe znaki na początku kolejnej linii. Przykład: <html><div style="margin-top:-1.2em"></div></html> <code> To: <first_recepient@example.com>, <second_recepient@example.com>, <third_recepient@example.com> </code> <html><div style="margin-left:0.5em;padding-left:0.5em;border-left:1px gray solid;display:block; margin-bottom: 0"></html> Although SMTP extensions may relax this restriction for the content body, the content header fields are always encoded using the US-ASCII repertoire. [[https://datatracker.ietf.org/doc/html/rfc5321#section-2.3.1|[RFC dla SMTP]]] <html></div></html> W niektórych nagłówkach można użyć znaków spoza kodowania US-ASCII, ale muszą one być odpowiednio zakodowane, używając składni //encoded-word// opisanej w odpowiednim [[https://datatracker.ietf.org/doc/html/rfc2047|dokumencie RFC]]. \\ Np: ''Mój przykładowy tekst'' (gdzie w UTF-8 ''ó'' to binarnie ''\0xC3\0xB3'' a ''ł'' to ''\xC5\x82'') można w nagłówku //Subject// zakodować jako: \\ ''=?UTF-8?Q?M=C3=B3j?= =?UTF-8?Q?Przyk=C5=82adowy?= tekst'' lub ''=?UTF-8?Q?M=C3=B3j_przyk=C5=82adowy_tekst?='' (używając //__Q__uoted-Printable//) lub ''=?UTF-8?B?TcOzaiBwcnp5a8WCYWRvd3kgdGVrc3Q=?='' (używając //__b__ase64//). === Podstawowe nagłówki === Na liście nagłówków **musi** się znaleźć nagłówek ''Date'' i ''From''. \\ Format daty określa standard, w Linuksie można uzyskać prawidłowo sformatowaną datę komendą ''date --rfc-email''. Na liście nagłówków powinny znaleźć się też ''Message-ID'', oraz jeśli wiadomość jest odpowiedzią, ''In-Reply-To'' oraz ''References''. Na liście nagłówków powinien się znaleźć się też nagłówek ''Subject''. \\ Autor wiadomości musi też ustawić przynajmniej jeden z nagłówków ''To'', ''Cc'' lub ''Bcc'' (a jeżeli autor ustawi tylko ''Bcc'', to już MUA może usunąć ten nagłówek z treści i wiadomość transportowana po SMTP nie ma żadnych adresów docelowych w nagłówkach). ===== Agenci przy wysłaniu i odbieraniu maili ===== <small>Patrz też: [[https://en.wikipedia.org/wiki/Email_agent_(infrastructure)]]</small> === Wysłanie === <html><pre style="line-height:1em;font-family:DejaVu Sans Mono;margin-bottom:0"> ____ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ .------. (mail) → │ MUA │-→-→-→│ MSA │-→-→-→│ MTA │-→-→-→│ MTA │-→-→-→│ MDA │ → (skrzynka) ‾‾‾‾ └─────┘ SMTP └─────┘ SMTP └─────┘ SMTP └─────┘ SMTP └─────┘ `------‘ \____/ \_________________/ \____/ wysłanie przekazanie dostarcznie (submission) (relay) (delivery) </pre></html> Podział MTA na MSA, MTA i MDA jest umowny. \\ MSA poza przekazaniem wiadomości do kolejnego serwera sprawdza czy nadawcy wolno wysłać taki mail i wykonuje dodatkowe akcje wstępnie przetwarzające wiadomość, np. podpisuje wiadomość kluczem DKIM, usuwa nagłówki //Bcc// jeśli MUA tego nie zrobił. \\ MTA tylko przesyłają wiadomość do kolejnego serwera. \\ MDA ma za zadanie dostarczyć otrzymaną wiadomość do skrzynki (np. zapisać do pliku na dysku bądź przekazać lokalnemu programowi który trzyma skrzynki mailowe). \\ <small>Więcej znajdziesz w odpowiednim [[https://datatracker.ietf.org/doc/html/rfc5068|RFC]]</small> Współcześnie każdy kolejny agent odbierając wiadomość sprawdza czy ta nie jest spamem. === Odbieranie === <html><pre style="line-height:1em;font-family:DejaVu Sans Mono;margin-bottom:0"> .------. ┌─────┐ ┌─────────┐ (skrzynka) ← │ MAA │ ← ← ← │ MRA/MUA │ `------‘ └─────┘ POP3/IMAP └─────────┘ </pre></html> Po tym jak wiadomość wyląduje w skrzynce, trzeba ją stamtąd pobrać. Do tego używa się protokołów protokołu POP3 lub IMAP. ===== Protokół SMTP ===== ==== Komendy ==== Kolejne kroki komunikacji SMTP, przy założeniu że serwer zaakceptuje wszystkie polecenia: (<small>więcej w RFC [[https://datatracker.ietf.org/doc/html/rfc5321#section-4.1.1|dla SMTP]] i [[https://datatracker.ietf.org/doc/html/rfc4954|dla AUTH]]</small>): <html><div style="margin-top:-1.2em"></div></html> - serwer przesyła do świeżo połączonego klienta powitanie zaczynające się od kodu ''220'' - klient musi się przedstawić komendą ''EHLO //nazwa_domenowa//'' (lub starszym ''HELO //nazwa_domenowa//'') i poczekać na akceptację serwera - klient może poprosić o uwierzytelnienie komendą ''AUTH //metoda//''; w wynikach komendy ''EHLO'' podane są wspierane przez serwer metody (<small>lista ustandaryzowanych metod jest [[https://www.iana.org/assignments/sasl-mechanisms|tutaj]]</small>) * po wykonaniu ''AUTH //metoda//'' klient musi poczekać na odpowiedź; serwer zwróci albo kod 5xx określający że się nie zgadza, albo odpowiedź spodziewaną w wybranej metodzie * serwer zwykle pozwala na uwierzytelnienie tylko jeżeli nawiązano z nim bezpieczne połączenie (TLS) * w powszechnie używanej metodzie ''AUTH PLAIN'': * serwer odsyła kod 334 i czeka na dane uwierzytelniające * klient musi przesłać nazwę użytkownika i hasło zapisane jako ''\0//użytkownik//\0//hasło//'' i zakodowane w base64. \\ aby przygotować dane dla metody //PLAIN//, możesz wykonać: \\ ''echo -n "User:"; read -rs U; echo -n "\nPass:"; read -rs P; echo; printf "\0%s\0%s" "$U" "$P" | base64'' * serwer po udanym uwierzytelnieniu odsyła odpowiedź z kodem 235 - klient musi wysłać informację o nadawcy maila komendą ''MAIL FROM://nadawca//'' i poczekać na akceptację serwera - klient musi wysłać informację o jednym odbiorcy maila komendą ''RCPT TO://odbiorca//'' i poczekać na akceptację serwera - klient może wskazać kolejnego odbiorcę powtarzając komendę //RCPT TO// z kolejnymi adresami - klient zgłasza że chce podać treść maila komendą ''DATA'' i czeka na odpowiedź od serwera (354) - klient podaje treść maila, zakończoną liną składającą się z kropki \\ <small>jeżeli linia zaczyna się od kropki, serwer usuwa tą kropkę; więc żeby wysłać maila z linią złożoną z kropki, trzeba podać '..'</small> - po odebraniu ''\r\n.\r\n'' serwer wysyła akceptację do klienta - klient może wysłać kolejny mail (zaczynając znów od ''MAIL FROM'') lub zakończyć połączenie wysyłając komendę ''QUIT'' W SMTP odpowiedź na niektóre komendy może składać się z wielu linii. W takim przypadku wszystkie poza ostatnią linią mają składnię ''kod-treść'', a ostatnia linia ''kod treść''. \\ Klient może wysłać następną komendę dopiero po otrzymaniu odpowiedzi na poprzednią. Przykład komunikacji: <html><div style="margin-top:-1.2em"></div></html> <html><pre> <span style="color:#007">220 example.org ESMTP</span> <span style="color:#700">EHLO sub.domain.baz</span> <span style="color:#007">250-example.org hello sub.domain.baz</span> <span style="color:#007">250-AUTH LOGIN PLAIN</span> <span style="color:#007">250 8BITMIME</span> <span style="color:#700">AUTH PLAIN</span> <span style="color:#007">334 </span> <span style="color:#700">AHVzZXIAcGFzc3dvcmQ=</span> <span style="color:#007">235 Authentication succeeded</span> <span style="color:#700">MAIL FROM:user@example.org</span> <span style="color:#007">250 OK</span> <span style="color:#700">RCPT TO:friend@example.org</span> <span style="color:#007">250 Accepted</span> <span style="color:#700">RCPT TO:mellon@doriath.mi</span> <span style="color:#007">250 Accepted</span> <span style="color:#700">DATA</span> <span style="color:#007">354 Enter message, ending with "." on a line by itself</span> <span style="color:#700">From: <user@example.org></span> <span style="color:#700">Date: Mon, 13 Jan 2025 00:00:00 +0000</span> <span style="color:#700"></span> <span style="color:#700">Zorg</span> <span style="color:#700">.</span> <span style="color:#007">250 OK id=1tXOtg-007aSz-0m</span> <span style="color:#700">QUIT</span> <span style="color:#007">221 example.org closing connection</span> </pre></html> SMTP definiuje też komendy: * ''NOOP'' (no-operation), ''RSET'' (reset) i ''HELP'' * ''VRFY'' i ''EXPN'', współcześnie zwykle wyłączone albo z dostępem tylko dla zalogowanych użytkowników * <small>opcjonalnie ''BDAT'' do sensowniejszego wysyłania danych – patrz [[https://datatracker.ietf.org/doc/html/rfc3030|RFC]]</small> * ''STARTTLS'' do zmiany połączenia w szyfrowane (patrz [[https://datatracker.ietf.org/doc/html/rfc3207|RFC]]) ==== Porty używane przez SMTP ==== SMTP używa portów: * 25 (''smtp'') do nieszyfrowanych połączeń * <small>25 (''smtp'') do szyfrowanych połączeń (TLS), ustanawianych po użyciu komendy ''STARTTLS'' na nieszyfrowanym połączeniu</small> * <small>465 (''smtps'', znane też jako ''urd'') do szyfrowanych połączeń (TLS)</small> * <small>587 (''submission'') do nieszyfrowanych połączeń</small> * 587 (''submission'') do szyfrowanych połączeń (TLS), ustanawianych po użyciu komendy ''STARTTLS'' na nieszyfrowanym połączeniu * <small>2525 (bez nazwy) niestandardowy port, używany w przypadku jeśli port 25 jest niedostępny</small> <small>(Zobacz też: https://www.cloudflare.com/learning/email-security/smtp-port-25-587/)</small> Połączenie bez szyfrowania można wykonać np. programem ''socat'' (lub ''nc'', jeśli serwer przeżyje kończenie linii przez samo ''\n''): \\ ''socat tcp://adres_serwera//:smtp,crlf readline'' \\ <small>lub tandetniejsze ''socat tcp://adres_serwera//:smtp,crlf stdio'' jeśli masz [[https://manpages.debian.org/testing/socat/socat.1.en.html#BUGS|debianopochodnego]] Linuksa </small> <small> Połączenie od razu z szyfrowania można wykonać np. programem ''socat'' lub ''openssl'': \\ ''socat ssl://adres_serwera//:smtps,crlf readline'' \\ ''openssl s_client -quiet -verify_quiet -crlf //adres_serwera//:smtps'' </small> Na portach 25 i 587 połączenie początkowo jest nieszyfrowane. Klient musi wysłać najpierw polecenie ''EHLO //nazwa_domenowa//'', następnie wysłać polecenie ''STARTTLS'', po akceptacji którego następuje nawiązanie połączenia TLS. \\ Program ''openssl s_client'' umie w taki właśnie sposób nawiązać połączenie z serwerem SMTP po podaniu komendy: \\ ''openssl s_client -quiet -verify_quiet -crlf -starttls smtp //adres_serwera//:submission'' \\ <small>Można też wskazać własną nazwę wpisywaną do komendy EHLO przez: \\ ''openssl s_client -quiet -verify_quiet -crlf -starttls smtp -name //nazwa_domenowa_do_ehlo// //adres_serwera//:submission''</small> \\ Po nawiązaniu połączenia TLS klient powinien ponownie wysłać komendę ''EHLO'' (a serwer powinien zapomnieć o poprzedniej). ==== Zadania ==== ~~Zadanie.#~~ Znajdź dowolną stronę oferującą usługę typu //10 minute mail//. Zostawiając do kolejnych ćwiczeń otwartą kartę ze swoim 10-cio minutowym adresem mail w przeglądarce, sprawdź jaki serwer obsługuje pocztę dla domeny z której jest ten adres. ~~Zadanie.#~~ Przygotuj do skopiowania i wklejania (np. w edytorze tekstu) treść komunikacji od klienta do serwera bez uwierzytelniania, w tym treść samej wiadomości. \\ W zawartości wiadomości mają się znaleźć nagłówki //From//, //To//, //Subject// i //Date//. \\ Zarówno //RCPT TO// jak i //To// mają wskazywać na twój 10-cio minutowy adres. ~~Zadanie.#~~ Połącz się bez szyfrowania z serwerem odbierającym maile z domeny twojego 10-cio minutowego maila i wyślij wcześniej przygotowany mail. Następnie sprawdź czy dotarł i czy został prawidłowo zrozumiany przez pocztę. ~~Zadanie.#~~ Przygotuj polecenia które będziesz musiał wpisać żeby wysłać mail ze swojej poczty studenckiej (albo innej własnej poczty) z uwierzytelnieniem metodą PLAIN do adresów dwóch osób siedzących obok (<small>lub do innych swoich adresów, wedle uznania</small>). \\ W zawartości wiadomości mają się znaleźć __prawidłowe__ nagłówki //From//, //To// lub //Cc//, //Subject// i //Date// oraz niepusta treść maila. ~~Zadanie.#~~ Połącz się używając portu 587 (''submission'') z użyciem STARTTLS do serwera obsługującego twoją pocztę i wyślij wcześniej przygotowany mail. Następnie sprawdź czy dotarł i jak wygląda. ===== Protokół POP3 i IMAP ===== ==== POP3 ==== Przykładowa komunikacja: <html><div style="margin-top:-1.2em"></div></html> - klient uwierzytelnia się, wykonując jedno z: * wysyła komendę ''USER //nazwa//'' i komendę ''PASS //hasło//'' * wysyła komendę ''AUTH //metoda//'' (podobnie jak dla SMTP), np. ''AUTH PLAIN'', po której wysyła dane uwierzytelniające - klient wysyła komendę ''LIST'' (lub opcjonalnie wspierane ''UIDL'') i dostaje listę numerów wiadomości (lub listę numerów wraz z unikalnym identyfikatorem wiadomości) - klient wysyła komendę ''RETR //numer//'' pobierającą wiadomość o podanym numerze (tyle razy ile potrzebuje) - klient wysyła komendę ''DELE //numer//'' zaznaczając wiadomość o podanym numerze jako do usunięcia (tyle razy ile potrzebuje) - klient wysyła komendę ''QUIT'' która usuwa wcześniej oznaczone wiadomości Numery na liście wiadomości to kolejne liczby naturalne, po usunięciu wiadomości i ponownym połączeniu wiadomości są numerowane na nowo. Poza powyższymi, z istotnych funkcji protokół POP3 dopuszcza jeszcze komendę pobierającą nagłówki i pierwsze //N// linii treści wiadomości (''TOP'') oraz wyświetlającą które z opcjonalnych funkcji są wspierane przez serwer (''CAPA''). <small>Więcej w RFC [[https://datatracker.ietf.org/doc/html/rfc1939|dla POP3]] i [[https://datatracker.ietf.org/doc/html/rfc2449|rozszerzeń do POP3]].</small> POP3 używa portu 110 dla nieszyfrowanej komunikacji TCP i portu 995 dla szyfrowanej komunikacji SSL/TLS. POP3 **nie** wspiera: * oznaczania maili jako przeczytanych, ważnych etc., * używania katalogów, * czekania na nowe maile. POP3 powstał po to, żeby użytkownik pobrał z serwera maile na swój komputer, usunął je z serwera zwalniając miejsce na kolejne maile. Tworząc ten protokół nie przewidziano korzystania z poczty na wielu komputerach ani istnienia klientów pocztowych innych niż lokalny program (protokół powstawał rok przed HTTP). Wiele serwerów poczty wciąż oferuje POP3, stąd warto znać różnice między tym protokołem a protokołem IMAP. ==== IMAP ==== W tej chwili powszechnie używana jest wersja [[https://datatracker.ietf.org/doc/html/rfc3501|IMAPv4rev1]] oraz [[https://datatracker.ietf.org/doc/html/rfc9051|IMAPv4rev2]] (w dużym stopniu kompatybilna z poprzednią). **W protokole IMAP przed każdą komendą klient musi podać identyfikator (tag) będący dowolnym wymyślonym przez klienta ciągiem alfanumerycznym.** \\ Przykładowa komunikacja w której klient wybrał tagi ''foo'' i ''baz'': <html><pre style="margin-bottom:0"> <span style="color:#700"><b>foo</b> search subject "SK2"</span> <span style="color:#700"><b>baz</b> search subject "sieci"</span> <span style="color:#007">* SEARCH 2 5 7 10</span> <span style="color:#007"><b>foo</b> OK SEARCH completed</span> <span style="color:#007">* SEARCH 5 7 10 12</span> <span style="color:#007"><b>baz</b> OK SEARCH completed</span> </pre></html> Klient nie powinien powtarzać tagów. <small>Większość programów generuje tagi doklejając kolejne numery za literę ''A'', tzn. ''A001'', ''A002'', …</small> \\ Klient może wysłać komendę zanim dostał odpowiedź na poprzednią, a serwer może wykonywać komendy równolegle, natomiast musi wysyłać odpowiedzi w kolejności. W odpowiedzi na komendę serwer może przesłać linię zaczynającą się od: * ''+'' serwer czeka na wpisanie czegoś przez klienta (np. w komendzie ''AUTHENTICATE'' na dane uwierzytelniające), * ''*'' serwer przesyła linię z treścią odpowiedzi na komendę, * tagu, kiedy serwer wysyła status wykonana komendy (''OK''/''NO''/''BAD''). Przykładowa komunikacja może składać się z: <html><div style="margin-top:-1.2em"></div></html> - po połączeniu, serwer przesyła klientowi powitanie - klient wysyła komendę ''CAPABILITY'', dostaje w odpowiedzi możliwości serwera - klient uwierzytelnia się, wykonując jedno z: * wysyła komendę ''LOGIN //nazwa// //hasło//'' * wysyła komendę ''AUTHENTICATE //metoda//'' (podobnie jak dla SMTP), np. ''AUTHENTICATE PLAIN'', po której wysyła dane uwierzytelniające - zalogowany klient może między innymi: * zbadać strukturę skrzynki, np. komendą ''LIST "" *'' * stworzyć, zmienić nazwę czy usunąć katalogi * czekać na przyjście nowych wiadomości (o tym jest dalej w materiałach) * dodać nową wiadomość do wskazanego katalogu, np. dodać szkic wiadomości - klient wybiera katalog który chce otworzyć w trybie zapisu i odczytu komendą ''SELECT //nazwa//'' lub trybie tylko do odczytu komendą ''EXAMINE //nazwa//'' - po wybraniu katalogi, klient może: * pobrać wiadomość bądź jej wskazane części komendą ''FETCH …'', \\ np: ''fetch 5 FULL'' pobierze wszystkie metadane wiadomości nr 5, ''fetch 6 BODY[]'' pobierze zawartość wiadomości nr 6, a ''fetch 100:200 BODY[HEADER.FIELDS (FROM TO DATE SUBJECT)]'' pobierze nagłówki //From//, //To//, //Date// i //Subject// dla wiadomości od 100 do 200 \\ <small> Komenda ''Fetch'' jest [[ https://datatracker.ietf.org/doc/html/rfc3501#page-55|rozbudowana]] tak by w sprawny sposób można było przeglądać wiadomości bez ściągania z wszystkich wiadomości serwera</small> * zmienić flagi wiadomości komendą ''STORE …'', \\ np. ''STORE 42 +FLAGS (\Deleted)'' dodaje (patrz: ''+'') jedyną w podanym zbiorze (patrz: ''(…)'') flagę do wiadomości nr 42 określającą że wiadomość jest usunięta (''\Deleted'') \\ np. ''STORE 56 +FLAGS (\Seen \Answered)'' doda dwie flagi, ''STORE 10:50 -FLAGS (\Flagged)'' usunie oznaczenie wiadomości jako ważnej dla wiadomości od 10 do 50 * usunąć wiadomości z ustawioną flagą ''\Deleted'' komendą ''EXPUNGE'' * wyszukać wiadomości komendą ''SEARCH …'', \\ np. ''SEARCH UNSEEN'' pokaże identyfikatory nieprzeczytanych wiadomości, ''SEARCH SUBJECT "foo"'' pokaże identyfikatory wiadomości które w tytule mają ciąg znaków ''foo'' \\ <small>Komenda ''SEARCH'' ma spore możliwości, patrz [[https://datatracker.ietf.org/doc/html/rfc3501#page-51|RFC]]; ta komenda ma pozwalać przeszukać skrzynkę bez ściągania z serwera wszystkich wiadomości</small> * skopiować bądź przenieść wiadomość do innego katalogu * wrócić do stanu zalogowanego komendą ''UNSELECT'' - do zakończenia pracy klient używa komendy '''LOGOUT'' IMAP używa dwóch numerów wiadomości: kolejnych numerów w skrzynce, zmieniających się po usunięciu wiadomości, i unikalnych identyfikatorów, nadawanych jako kolejne liczby naturalne. \\ Jeżeli komendy ''STORE'', ''FETCH'', ''SEARCH'', … zostaną poprzedzone komendą ''UID'', to operują na unikalnych identyfikatorach. \\ Po wybraniu katalogu klient zawsze dostaje informację o tym jaki UID zostanie nadany kolejnej wiadomości, co pozwala np. zorientować się jakie wiadomości pojawiły się od ostatniego sprawdzania poczty. \\ Przy okazji każdej odpowiedzi serwer może przesłać dodatkowo np. linię ''* //num// EXISTS'' wskazując że w skrzynce pojawiła się wiadomość //num//. W IMAP kiedykolwiek po zalogowaniu klient może też wysłać komendę **''IDLE''** ([[https://datatracker.ietf.org/doc/html/rfc2177.html|RFC]]). W odpowiedzi na nią serwer wysyła linię zaczynającą się od ''+'' i czeka na wysłanie przez klienta linii składającej się ze słowa ''DONE'', ale jednocześnie serwer będzie na bieżąco raportować zdarzenia na skrzynce (takie jak pojawienie się nowych maili) wysyłając linie zaczynające się od ''*''. \\ Klient musi co nie więcej niż pół godziny wysyłać ''DONE'' i ponawiać komendę ''IDLE'' jako keepalive pozwalający serwerowi poradzić sobie z zerwanymi połączeniami. Przykład komunikacji: <html><div style="margin-top:-1.2em"></div></html> <html><pre> <span style="color:#700">A CAPABILITY</span> <span style="color:#007">* CAPABILITY IMAP4rev1 IDLE UNSELECT</span> <span style="color:#007">A OK CAPABILITY completed</span> <span style="color:#700">B LOGIN user@example.org qwerty</span> <span style="color:#007">B OK [CAPABILITY IMAP4 IMAP4rev1 IDLE UNSELECT] User logged in</span> <span style="color:#700">C LIST "" *</span> <span style="color:#007">* LIST (\HasNoChildren) "/" "INBOX"</span> <span style="color:#007">* LIST (\HasNoChildren \Drafts) "/" "Drafts"</span> <span style="color:#007">* LIST (\HasNoChildren \Junk) "/" "Junk"</span> <span style="color:#007">* LIST (\HasNoChildren \Sent) "/" "Sent"</span> <span style="color:#007">* LIST (\HasNoChildren \Trash) "/" "Trash"</span> <span style="color:#007">C OK LIST completed</span> <span style="color:#700">D SELECT "INBOX"</span> <span style="color:#007">* FLAGS (\Answered \Deleted \Draft \Flagged \Seen)</span> <span style="color:#007">* 50 EXISTS</span> <span style="color:#007">* 0 RECENT</span> <span style="color:#007">* OK [UNSEEN 48]</span> <span style="color:#007">* OK [UIDNEXT 85]</span> <span style="color:#007">D OK [READ-WRITE] Completed</span> <span style="color:#700">E SEARCH UNSEEN</span> <span style="color:#007">* SEARCH 48 50</span> <span style="color:#007">E OK SEARCH completed</span> <span style="color:#700">F UID SEARCH UNSEEN</span> <span style="color:#007">* SEARCH 82 84</span> <span style="color:#007">F OK completed</span> <span style="color:#700">G SEARCH SINCE 1-JAN-2025</span> <span style="color:#007">* SEARCH 46 47 48 49 50</span> <span style="color:#007">G OK SEARCH completed</span> <span style="color:#700">H FETCH 49:50 BODY.PEEK[HEADER.FIELDS (SUBJECT)]</span> <span style="color:#007">* 49 FETCH (BODY[HEADER.FIELDS (SUBJECT)] {30}</span> <span style="color:#007">Subject: Meeting on Monday</span> <span style="color:#007">)</span> <span style="color:#007">* 50 FETCH (BODY[HEADER.FIELDS (SUBJECT)] {33}</span> <span style="color:#007">Subject: Re: Meeting on Monday</span> <span style="color:#007">)</span> <span style="color:#007">H OK FETCH completed</span> <span style="color:#700">I FETCH 50 BODY[]</span> <span style="color:#007">* 50 FETCH (BODY[] {715}</span> <span style="color:#007">Return-Path: <mellon@doriath.mi></span> <span style="color:#007">Received: from mx.doriath.mi</span> … <span style="color:#007">Subject: Re: Meeting on Monday</span> <span style="color:#007">Ok, pasuje.</span> <span style="color:#007">)</span> <span style="color:#007">I OK FETCH completed</span> <span style="color:#700">J IDLE</span> <span style="color:#007">+ idling</span> <span style="color:#007">* 51 EXISTS</span> <span style="color:#007">DONE</span> <span style="color:#007">J OK IDLE completed</span> <span style="color:#700">K LOGOUT</span> <span style="color:#007">* BYE mail.example.org server closing connection</span> <span style="color:#007">K OK LOGOUT completed</span> </pre> </html> IMAP używa do portów TCP: <html><div style="margin-top:-1.2em"></div></html> - 143 (''imap'') do nieszyfrowanej komunikacji, - 143 (''imap'') do szyfrowanych połączeń (TLS), ustanawianych po użyciu komendy ''STARTTLS'' na nieszyfrowanym połączeniu, - 993 (''imaps'') do szyfrowanych połączeń (TLS). Odpowiednia komenda dla nawiązania połączenia z użyciem STARTTLS dla narzędzia ''openssl'' to: \\ ''openssl s_client -quiet -verify_quiet -crlf -starttls imap //adres_serwera_imap//:imap'' ==== Zadania ==== ~~Zadanie.#~~ Połącz się do swojej poczty studenckiej używając IMAP i znajdź nieprzeczytane wiadomości w katalogu ''Inbox''. ~~Zadanie.#~~ Znajdź, używając UIDów, wiadomości z katalogu ''Inbox'' które mają w temacie "SK2" (albo inny wybrany ciąg znaków). Wyświetl nagłówki jednej z tych wiadomości (np. komendą ''UID FETCH //num// BODY[HEADER]''). ~~Zadanie.#~~ Wykonaj komendę ''IDLE'' i w trakcie jej trwania wyślij sobie maila. Następne zakończ komendę IDLE, wyświetl otrzymaną wiadomość i oznacz ją jako przeczytaną lub usuniętą. ==== [ekstra] Sieve - filtracja na serwerze ==== Wstępne przetworzenie maili trafiających do skrzynki na serwerze, np. wrzucanie do wybranych folderów na podstawie ustawionych filtrów, umożliwiają skrypty sieve (patrz: [[https://datatracker.ietf.org/doc/html/rfc5228|RFC]] [[http://sieve.info/|strona "domowa"]]) które można konfigurować używając [[https://datatracker.ietf.org/doc/html/rfc5804|dedykowanego do tego protokołu]]. \\ Oczywiście sieve musi być wspierany przez serwer poczty i włączony przez administratora tego serwera. ===== Budowa wiadomości e-mail ===== ==== Nagłówki ==== === Received === Każdy serwer SMTP dodaje nagłówek //Received// na początek każdej przetwarzanej wiadomości. Pozwala to określić przez jakie serwery przeszedł mail (szczegóły w [[https://datatracker.ietf.org/doc/html/rfc5321#section-4.4|RFC]]). Nagłówek //Received// zawiera między innymi: * identyfikację serwera który odebrał wiadomość, * identyfikację serwera z którego przyszła wiadomość, * datą odebrania (uwaga na strefy czasowe!), * zwykle zawiera identyfikator pozwalający znaleźć w logach serwera informacje o tej wiadomości, * może zawierać, za słowem kluczowym ''for'' informację o adresie wpisanym w ''RCPT TO'' z "koperty" SMTP. ~~Zadanie.#~~ Prześledź nagłówki maila wysłanego do lub z poczty jakiegoś dużego serwera pocztowego. Przez ile serwerów przeszedł ten mail? Ile z nich jest częścią wewnętrznej infrastruktury nadawcy/odbiorcy? ~~Zadanie.#~~ Prześledź nagłówki dowolnego maila ze spamem. Jak mają się adresy podane za słowem kluczowym ''for'' w nagłówku //Received// do adresów w //To// i //Cc//? === Adresy === Nagłówki z adresami mają składnię ''Nagłówek: nazwa <adres>[, …]'', np. \\ ''To: John Q. Public %%<john@example.com>, <smith@example.com>%%'' Poza oczywistymi //From//, //To//, //Cc// i //Bcc// używa się też nagłówków //Reply-To// do wskazania (jednego) adresu odpowiedzi i //Return-Path// do wskazania adresu na który maja być wysyłane komunikaty o niepowodzeniu dostarczenia wiadomości. Wiele serwerów pozwala dodawać na koniec adresu, po określonym znaku, dodatkowy tekst. \\ Np. jeżeli serwer pozwala na dodanie takiego tekstu po ''+'', to mail wysłany na adres ''john+shop@example.com'' trafi do tej samej skrzynki do której trafiłby mail wysłany na adres ''john@example.com''. Często pozwala to na łatwiejsze filtrowanie wiadomości i kontrolę spamu. (To czy i jaki znak jest używany zależy od konfiguracji serwera; przykłady dla wybranych serwerów są na [[https://en.wikipedia.org/wiki/Email_address#Sub-addressing|wikipedii]]). ~~Zadanie.#~~ Sprawdź nagłówki z adresami dowolnego maila z listy mailingowej. === Identyfikator wiadomości i powiązanie maila z odpowiedzią === Każdy mail powinien mieć ustawiony unikalny identyfikator w nagłówku //Message-ID//. Jeżeli MUA nie ustawił tego nagłówka, zrobi to MSA. Odpowiadając na mail MUA wpisuje w nagłówek //In-Reply-To// identyfikator maila na który użytkownik odpowiada, oraz kopiuje (bądź tworzy) nagłówek //References// i dodaje identyfikator tego maila na koniec listy identyfikatorów wiadomości tego wątku. ~~Zadanie.#~~ Znajdź mail będący odpowiedzią na odpowiedź odpowiedzi. Zobacz jak wyglądają nagłówki //In-Reply-To// i //References// i porównaj je z //Message-ID// odpowiedzi na odpowiedź. ==== Treść, załączniki i kodowanie ==== Określenie typu [[https://en.wikipedia.org/wiki/MIME|MIME]] powstało dla poczty – MIME to skrót od Multipurpose Internet Mail Extensions. === Nagłówek Content-Type === To czym jest treść wiadomości, określa nagłówek //Content-Type//. \\ Jeżeli nie podano nagłówka //Content-Type//, domyślnie przyjmowany jest czysty tekst (''text/plain''). \\ Jeżeli wiadomość składa się z jednej części, to w nagłówkach wiadomości można podać po prostu typ, np: \\ ''Content-Type: text/html; charset=utf-8''. === Content-Type: multipart/… === Jeżeli wiadomość składa się z więcej niż jednej części, używa się specjalnych typów \\ ''Content-Type: multipart/…; boundary=//separator//''. Te typy wskazują że treść to więcej niż jedna część i ustawiają separator oddzielający te części na ''--//separator//''. \\ Powszechnie wykorzystuje się kilka takich typów, np. ''mixed'' i ''alternate''. Każda część wiadomości ma powinna mieć powtórzony nagłówek //Content-Type// określający jakiego typu jest ta część, może mieć dodatkowe nagłówki porządkujące treść i te nagłówki muszą być oddzielone pustą linią od treści. === Wiadomość HTML + plain tekst === Typ ''multipart/**alternate**'' służy podaniu kilku wersji tego samego maila i jest powszechnie używany do wysyłania maila jednocześnie w wersji HTML i czystego tekstu. Przykład takiej treści: <html><div style="margin-top:-1.2em"></div></html> <code> … inne nagłówki … Content-Type: multipart/alternate; boundary=oddzielacz --oddzielacz Content-Type: text/plain Przyjdzie o **jedenastej** wieczorem. --oddzielacz Content-Type: text/html <html><body><p>Przyjdzie o <b>jedenastej</b> wieczorem.</p></body></html> --oddzielacz </code> ~~Zadanie.#~~ Znajdź w swojej skrzynce mail który ma dwie wersje. Czy faktycznie wersje są równoważne? Którą wyświetla domyślnie twój klient pocztowy? === Załączniki === Typ ''multipart/**mixed**'' służy do wysłania kilku niezależnych części i jest używany do wysyłania z załącznikami. Przykład: <html><div style="margin-top:-1.2em"></div></html> <code> … inne nagłówki … Content-Type: multipart/mixed; boundary=fikusny_separator --fikusny_separator Content-Type: text/plain Zobacz ten obrazek! --fikusny_separator Content-Type: image/png Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="mail.png" iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAATElEQVQY04WOOQ7AQAwCZ1b+/5dJ ETvHpgjyISFAGN5YCNgjrP7GURBzioYgzEHcQ9mIFMRLHykg2AtU+0bVxCNq8am+oe6OJ8yf5QDW ShMmZmKfpQAAAABJRU5ErkJggg== --fikusny_separator </code> ~~Zadanie.#~~ Znajdź w swojej skrzynce mail z załącznikami. Jaki //Content-Transfer-Encoding// został użyty do przesłania załączników? === [ekstra] Dwie wersje i załączniki naraz... === Typu MIME moża w sobie dowolnie zagnieżdżać, więc można również: <code> … inne nagłówki … Content-Type: multipart/mixed; boundary=a --a Content-Type: multipart/alternative; boundary=b --b Content-Type: text/plain Zobacz ten obrazek! [IMG] --b Content-Type: multipart/related; boundary=c --c Content-Type: text/html <html><body><p>Zobacz ten obrazek!</p> <p><img src="cid:my-mail-img""></p></body></html> --c Content-Type: image/png Content-Transfer-Encoding: base64 Content-ID: <my-mail-img> iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAATElEQVQY04WOOQ7AQAwCZ1b+/5dJ ETvHpgjyISFAGN5YCNgjrP7GURBzioYgzEHcQ9mIFMRLHykg2AtU+0bVxCNq8am+oe6OJ8yf5QDW ShMmZmKfpQAAAABJRU5ErkJggg== --c --b --a Content-Type: text/plain Content-Disposition: attachment; filename="licencja.txt" kopyrajt 2025 --a </code> ==== Kodowanie treści ==== O ile nagłówki wiadomości używają siedmiobitowego US-ASCII ze wsparciem dla encoded-words i trzymają się ograniczenia długości linii, o tyle w treści można zmienić kodowanie na sensowniejsze. Kodowanie dla danej części wiadomości można ustawić w nagłówku //Content-Transfer-Encoding//. Domyślna wartość to ''7bit'', nie pozwalająca w ogóle na użycie znaków spoza US-ASCII. Inne dozwolone kodowana to "normalne" ''8bit'' i ''binary'' (pierwsze ogranicza długość linii do 998 znaków, drugie nie nakłada ograniczenia na długość linii) oraz ''quoted-printable'' i ''base64''. ''Content-Transfer-Encoding: quoted-printable'' ([[https://datatracker.ietf.org/doc/html/rfc2045#section-6.7|RFC]]) bez zmian przesyła drukowalne znaki ASCII poza znakiem równości, natomiast całą resztę (w tym np. spacje czy znaki nowej linii) koduje jako ''=//XX//'', gdzie //XX// to szesnastkowa wartość kodowanego znaku. Powstały tekst zawija się przed 77 znakiem , wstawiając na koniec linii znak ''=''. \\ Np. ''Einstein napisał: e=mc²'' z nową linią na końcu stanie się tekstem ''Einstein=20napisa=C5=82:=20e=3Dmc=C2=B2=0D=0A''. ''Content-Transfer-Encoding: quoted-printable'' używa zwykłego ''base64'' do zakodowania treści. \\ Np. ''Einstein napisał: e=mc²'' z nową linią na końcu stanie się tekstem ''RWluc3RlaW4gbmFwaXNhxYI6IGU9bWPCsg0K''. \\ Kodowanie ''base64'' jest powszechnie używane do przesyłania nietekstowych załączników i jest do tego celu niewydajne – base64 koduje 3 bit treści na 4 bitach danych, więc objętość wiadomości rośnie o ⅓. ~~Zadanie.#~~ Wyszukaj w swojej skrzynce przynajmniej dwa maile z polskimi znakami w treści które używają różnych ''Content-Transfer-Encoding''.
sk2/mail.1736824068.txt.gz
· ostatnio zmienione: 2025/01/14 04:07 (edycja zewnętrzna)
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Złóż / rozłóż wszystko
Do góry