Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pc:laboratoare:11 [2022/05/14 02:08]
bogdan_costel.mocanu [Protocoalele SMTP, POP3 și IMAP]
pc:laboratoare:11 [2023/05/07 17:56] (current)
dorinel.filip [Exerciții] New domain
Line 1: Line 1:
-===== Laboratorul 11 - E-mail ​& DNS =====+===== Laboratorul 11 - DNS & E-mail =====
  
  
Line 28: Line 28:
  
 ==== Introducere ==== ==== Introducere ====
- 
-Primul mesaj e-mail a fost transmis in 1971 de un inginer pe nume Ray Tomlinson. Până la acea dată, puteau fi trimise mesaje doar în cadrul aceluiași calculator. Marea îmbunătățire introdusă de Tomlinson a fost posibilitatea de a trimite mesaje între calculatoare diferite din Internet, folosind semnul ’@’ pentru a desemna mașina spre care se trimite mesajul. 
- 
-Azi se trimit miliarde de mesaje e-mail pe zi, si totuși multe din caracteristicile de atunci ale mesajelor au rămas. Vom vedea în continuare structura mesajelor e-mail si modul în care sunt transmise acestea în Internet. 
  
 Programele se refera rareori la sisteme gazdă, cutii poștale și alte resurse prin adresele lor binare. În loc de numere binare, se utilizează șiruri ASCII, cum ar fi //​user@cs.pub.ro//​. Cu toate acestea, rețeaua înțelege numai adrese binare, deci este necesar un mecanism care să convertească șirurile ASCII în adrese de rețea. Protocolul care se ocupă de acest lucru se numește DNS (Domain Name System - sistemul numelor de domenii). Esența DNS-ului constă dintr-o schemă ierarhică de nume de domenii și dintr-un sistem de baze Programele se refera rareori la sisteme gazdă, cutii poștale și alte resurse prin adresele lor binare. În loc de numere binare, se utilizează șiruri ASCII, cum ar fi //​user@cs.pub.ro//​. Cu toate acestea, rețeaua înțelege numai adrese binare, deci este necesar un mecanism care să convertească șirurile ASCII în adrese de rețea. Protocolul care se ocupă de acest lucru se numește DNS (Domain Name System - sistemul numelor de domenii). Esența DNS-ului constă dintr-o schemă ierarhică de nume de domenii și dintr-un sistem de baze
 de date distribuite pentru implementarea acestei scheme de nume. Protocolul este definit in RFC-urile [[https://​tools.ietf.org/​html/​rfc1034|1034]] și [[https://​tools.ietf.org/​html/​rfc1035|1035]]. de date distribuite pentru implementarea acestei scheme de nume. Protocolul este definit in RFC-urile [[https://​tools.ietf.org/​html/​rfc1034|1034]] și [[https://​tools.ietf.org/​html/​rfc1035|1035]].
  
-==== Structura mesajelor e-mail ==== 
  
-Un mesaj e-mail a fost întotdeauna ​transmis ​în format plain-text (text clar)Chiar si prin adăugarea atașamentelormesajele de e-mail sunt trimise ​tot ca mesaje ​plain-text, prin folosirea unor mecanisme ​de codificare (//​uuencode/​uudecode//​//​MIME/​BASE64//​).+Primul ​mesaj e-mail a fost transmis ​in 1971 de un inginer pe nume Ray TomlinsonPână la acea dată, puteau fi trimise mesaje ​doar în cadrul aceluiași calculator. Marea îmbunătățire introdusă ​de Tomlinson a fost posibilitatea de a trimite mesaje între calculatoare diferite din Internetfolosind semnul ’@’ pentru a desemna mașina spre care se trimite mesajul.
  
-Un mesaj este format dintr-o secțiune de antete (headers)urmată ​de o secțiune cu conținutul mesajului. Structura antetelor este descrisă în [[https://​tools.ietf.org/​html/​rfc822|RFC 822]], [[https://​tools.ietf.org/​html/​rfc1521|RFC 1521]] și [[https://​tools.ietf.org/​html/​rfc1806|RFC 1806]], ele având în general următoarea structură:+Azi se trimit miliarde de mesaje e-mail pe zisi totuși multe din caracteristicile ​de atunci ale mesajelor au rămas.
  
-  * unul sau mai multe antete //​Received//,​ care indică ce cale a fost urmată de mesaj de la sursa până la destinație 
-  * //​Mime-Version//:​ versiunea MIME (Multipurpose Internet Mail Extensions) folosită, 1.0 in general 
-  * //​Content-Type//:​ //​text/​plain//​ pentru mesaje text, //​multipart/​mixed//​ pentru mesaje cu atașamente 
-  * //​Subject//:​ subiectul mesajului 
-  * //Date//: data și ora când a fost trimis mesajul 
-  * //Message ID//: un ID pentru mesaj, folosit pentru identificarea în mod unic a unui mesaj 
-  * //From//: numele și adresa de mail a expeditorului 
-  * //To//: numele și adresa de mail a destinatarului 
-  * //Cc//: carbon copy (alți destinatari) 
-  * alte antete introduse de clientul de e-mail folosit pentru a trimite mesajul. 
  
-Conținutul mesajului este textul propriu-zis,​ pentru mesajele în text clar fără atașamente. Se poate observa mai jos un exemplu de mesaj: 
- 
-<​code>​ 
-MIME-Version:​ 1.0 
-From: profesor@upb.ro 
-To: student@upb.ro 
-Subject: Tema 
-Content-Type:​ text/plain 
- 
-Draga student, 
- 
-Fa-ti tema! 
- 
-Cu bine, 
-Profesorul. 
-</​code>​ 
- 
-Mesajele cu atașamente pot folosi una din următoarele tehnici pentru codificarea acestora: 
- 
-  * //​uuencode//​ - la începuturile e-mail-ului,​ fișierele care se doreau trimise ​ trebuiau convertite în format text și invers prin folosirea utilitarelor numite //​uuencode/​uudecode//;​ și în ziua de azi, unii clienți de mail adaugă atașamentele la sfârșitul mesajelor, codificându-le cu algoritmul folosit de //​uuencode//​ 
-  * //​MIME/​Base64//​ - această tehnologie este cea recomandată pentru trimiterea de mesaje cu atașamente. 
- 
-Un mesaj cu atașamente codificate [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Basics_of_HTTP/​MIME_types|MIME]] arată în felul următor: 
- 
-<​code>​ 
-MIME-Version:​ 1.0 
-From: Student Studentescu <​student@upb.ro>​ 
-To: Profesor PC <​profesor@upb.ro>​ 
-Subject: Re: Tema 
-Content-Type:​ multipart/​mixed;​ boundary=abc 
- 
---abc 
-Content-Type:​ text/plain 
- 
-Atasez tema. 
- 
-Cu bine, 
-Studentul 
- 
---abc 
-Content-Type:​ text/plain 
-Content-Disposition:​ attachment; filename="​tema.c"​ 
- 
-#include <​stdio.h>​ 
-int main() 
-{ 
-    printf("​Aceasta este tema mea\n"​);​ 
-    return 0; 
-} 
---abc 
-</​code>​ 
- 
-Se observă faptul că părțile care compun mesajul sunt separate între ele printr-un șir de caractere separator (boundary string), specificat ca un parametru pentru antetul //​Content-Type//​. Fiecare parte poate avea la rândul ei propriile antete, care conțin în general tipul și numele fișierului din secțiunea respectivă. În cazul în care se trimit atașamente binare, acestea sunt codificate folosind schema numită Base64, descrisă în [[https://​tools.ietf.org/​html/​rfc1521|RFC 1521]]. 
- 
-==== Protocoalele SMTP, POP3 și IMAP ==== 
- 
-În terminologia folosită de sistemele de e-mail, există trei actori. Aceștia pot fi situați pe trei mașini diferite sau pot co-exista pe aceeași gazdă: 
- 
-  - Mail User Agent (MUA) - aplicația folosită de utilizator pentru a citi și trimite mesaje e-mail (clientul de e-mail); el nu primește direct mesaje, acesta fiind rolul Mailbox Server-ului 
-  - Mailbox Server - serverul care primește și stochează mesajele (server de e-mail) 
-  - Mail Transfer Agent (MTA) - aplicația care primește și retrimite mesajele spre un alt MTA sau spre un Mailbox Server (“router” de e-mail). 
- 
-=== SMTP === 
- 
-SMTP (Simple Mail Transfer Protocol) este un protocol care se folosește pentru trimiterea mesajelor electronice (de la un client către un server). Acesta se foloseste de portul 25 peste TCP și este descris în [[https://​tools.ietf.org/​html/​rfc821|RFC 821]] și [[https://​tools.ietf.org/​html/​rfc5321|RFC 5321]]. 
- 
-Mesajele necesare în SMTP pentru trimiterea unui e-mail sunt următoarele:​ 
- 
-<​code>​ 
-1: HELO client.upb.ro 
-2: MAIL FROM: <​profesor@upb.ro>​ 
-3: RCPT TO: <​student@upb.ro>​ 
-4: DATA 
-5: MIME-Version:​ 1.0 
-From: profesor@upb.ro 
-To: student@upb.ro 
-Subject: Tema 
-Content-Type:​ text/plain 
- 
-Draga student, 
-  ​ 
-Fa-ti tema! 
-    
-Cu bine, 
-Profesorul. 
-. 
-6: QUIT 
-</​code>​ 
- 
-Se trimite deci întâi o comandă "​HELO"​ cu numele de domeniu sau adresa IP a clientului pentru a iniția sesiunea, apoi o comandă "MAIL FROM" cu adresa sursei, "RCPT TO" pentru destinație,​ "​DATA"​ pentru date (e-mail-ul în sine) și "​QUIT"​ pentru a se închide sesiunea. Secțiunea de date trebuie neapărat terminată cu secvența de caractere ''​%%<​CR><​LF>​.<​CR><​LF>​%%''​ (adică o linie nouă urmată de un punct și apoi de încă o linie nouă). 
- 
-=== POP3 === 
- 
-POP3 (Post Office Protocol 3) este un protocol utilizat pentru citirea mesajelor electronice (de la un server către un client). Clientul va interoga periodic serverul, va descărca mesajele și le va șterge automat de pe server. Comunicația se realizează folosind portul 110 peste TCP, în felul următor: 
- 
-<​code>​ 
-1: USERNAME username 
-2: PASS password 
-3: LIST 
-4: RETR 1 
-5: QUIT 
-</​code>​ 
- 
-=== IMAP === 
- 
-IMAP (Internet Message Access Protocol) este un protocol care se folosește pentru citirea mesajelor electronice (de la un server catre un client). Clientul interoghează periodic serverul și poate cere mesaje complete sau doar porțiuni (header, body), și nu va șterge automat mesajele de pe server. Comunicația se realizează prin TCP, folosind portul 143. 
- 
-<​code>​ 
-1: LOGIN username password 
-2: LIST ""​ "​*"​ 
-3: EXAMINE Inbox 
-4: FETCH 1 BODY[] 
-5: LOGOUT 
-</​code>​ 
  
 ==== Protocolul DNS ==== ==== Protocolul DNS ====
Line 266: Line 137:
  
 Dacă totuși domeniul se află la distanță, iar local nu este disponibilă nici o informație despre el, atunci serverul de nume trimite un mesaj de cerere către serverul de nume de pe primul nivel al domeniului solicitat. De menționat că metoda de interogare este recursivă (recursive query), deoarece fiecare server care nu are informația cerută o caută în altă parte și raportează. Dacă totuși domeniul se află la distanță, iar local nu este disponibilă nici o informație despre el, atunci serverul de nume trimite un mesaj de cerere către serverul de nume de pe primul nivel al domeniului solicitat. De menționat că metoda de interogare este recursivă (recursive query), deoarece fiecare server care nu are informația cerută o caută în altă parte și raportează.
 +
 +=== API DNS ===
 +
 +== gethostbyname() și gethostbyaddr() ==
 +
 +Până de curând, pentru a afla un nume pe baza unei adrese IP și o adresă pe baza unui nume, se foloseau funcțiile [[https://​linux.die.net/​man/​3/​gethostbyname|gethostbyname()]] și [[https://​linux.die.net/​man/​3/​gethostbyaddr|gethostbyaddr()]],​ împreună cu structura //​hostent//​. Între timp, acest API pentru DNS a fost scos din uz.
 +
 +== getaddrinfo() ==
 +
 +<code C>
 +#include <​sys/​types.h>​
 +#include <​sys/​socket.h>​
 +#include <​netdb.h>​
 +
 +int getaddrinfo(const char *node, const char *service,
 +                const struct addrinfo *hints, struct addrinfo **res);
 +</​code>​
 +
 +Funcția [[https://​linux.die.net/​man/​3/​getaddrinfo|getaddrinfo()]] primește informații despre numele unei gazde și al unui serviciu Internet, și returnează adresa sau adresele corespunzătoare. Parametrul //node// reprezintă numele simbolic (sub forma unui șir de caractere) al mașinii căreia vrem sa-i aflăm adresa (de exemplu, node poate fi “www.google.com”). Mai poate de asemenea fi reprezentat ca un șir care conține o adresă IPv4 sau IPv6.
 +
 +Parametrul //service// specifică portul returnat în output, și poate fi pus pe NULL (caz în care portul din output rămâne neinițializat) sau poate fi dat ca un nume de serviciu (de exemplu, “http”) sau ca o valoare numerică (“80”).
 +
 +Parametrul //hints// reprezintă criterii pentru filtrarea adreselor întoarse de apelul funcției //​getaddrinfo()//​. Este de tipul //struct addrinfo//, definit mai jos:
 +
 +<code C>
 +struct addrinfo {
 +    int              ai_flags;
 +    int              ai_family;
 +    int              ai_socktype;​
 +    int              ai_protocol;​
 +    socklen_t ​       ai_addrlen;
 +    struct sockaddr *ai_addr;
 +    char            *ai_canonname;​
 +    struct addrinfo *ai_next;
 +};
 +</​code>​
 +
 +În cazul în care se dorește filtrarea, se pot completa unul sau mai multe din următoarele câmpuri (restul punându-se pe 0):
 +
 +  * //​ai_family//​ - se specifică familia de adrese pentru valorile returnate, putând fi setată ca AF_INET (pentru IPv4), AF_INET6 (pentru IPv6) sau AF_UNSPEC (pentru ambele)
 +  * //​ai_socktype//​ - se filtrează după tipul de socket (SOCK_DGRAM sau SOCK_STREAM,​ de exemplu)
 +  * //​ai_protocol//​ - se specifică protocolul setat în adresele returnate de funcția //​getaddrinfo()//​
 +  * //​ai_flags//​ - se pot seta o serie de flag-uri.
 +
 +În final, rezultatul este pus în parametrul //res//, fiind reprezentat ca o listă înlănțuită de structuri de tipul //​addrinfo//,​ care se parcurge prin intermediul câmpului //​ai_next//​. Din câmpul //ai_addr// al rezultatului,​ se pot citi informațiile despre adresa și portul stației gazdă căutate (prin cast la //struct sockaddr_in//,​ de exemplu).
 +
 +În caz de succes, funcția întoarce 0, iar în caz de eroare întoarce o valoare negativă, care poate fi interpretată prin intermediul funcției //​gai_strerror()//:​
 +
 +<code C>
 +const char *gai_strerror(int errcode);
 +</​code>​
 +
 +<note important>​
 +Parametrul //res// este alocat de către funcția //​getaddrinfo()//,​ însă el trebuie dezalocat explicit de către utilizator prin intermediul funcției //​freeaddrinfo()//:​
 +
 +<code C>
 +void freeaddrinfo(struct addrinfo *res);
 +</​code>​
 +</​note>​
 +
 +Pentru a afișa adresa IP (v4 sau v6) corespunzătoare numelui simbolic din parametrul //node//, se poate utiliza funcția //​inet_ntop()//:​
 +
 +<code C>
 +#include <​arpa/​inet.h>​
 +
 +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
 +</​code>​
 +
 +Primul parametrul specifică familia de protocoale (AF_INET sau AF_INET6), al doilea parametru reprezintă structura de adresă (adică, de exemplu, câmpurile //​sin_addr//​ sau //​sin6_addr//​ din structurile //​sockaddr_in//​ pentru IPv4 sau //​sockaddr_in6//​ pentru IPv6), al treilea parametru reprezintă un șir de caractere unde va fi scrisă adresa sub formă de string, iar ultimul parametru reprezintă dimensiunea șirului de caractere în octeți. Valoarea de retur a funcției este un pointer la un șir de caractere identic cu cel din parametrul //dst//, sau NULL în caz de eroare.
 +
 +== getnameinfo() ==
 +
 +
 +<code C>
 +#include <​sys/​socket.h>​
 +#include <​netdb.h>​
 +
 +int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *host,
 +                socklen_t hostlen, char *serv, socklen_t servlen, int flags);
 +</​code>​
 +
 +Funcția [[https://​linux.die.net/​man/​3/​getnameinfo|getnameinfo()]] realizează operația inversă față de //​getaddrinfo()//​. Mai precis, primește o adresă și returnează numele simbolic și serviciul specifice adresei respective. Primii doi parametri reprezintă adresa IP (v4 sau v6) care este căutată. Se trimit structuri specifice protocolului dorit (//​sockaddr_in//​ sau //​sockaddr_in6//​) și dimensiunea lor. Rezultatele apelului sunt puse în șirurile de caractere //host// și //serv//, care sunt alocate de către utilizator. Parametrii //hostlen// și //servlen// reprezintă dimensiunile celor două șiruri de caractere.
 +
 +Funcția returnează 0 dacă s-a reușit cererea DNS, sau o valoare negativă interpretată cu //​gai_strerror()//​ în caz contrar.
 +
 +=== Cereri DNS în Linux ===
 +
 +În Linux, pentru a obține adresele IP ale unei gazde, putem folosi unul din utilitarele //host// sau //​nslookup//:​
 +
 +<​code>​
 +$ host google.com
 +google.com has address 172.217.20.14
 +google.com has IPv6 address 2a00:​1450:​400d:​804::​200e
 +google.com mail is handled by 30 alt2.aspmx.l.google.com.
 +google.com mail is handled by 50 alt4.aspmx.l.google.com.
 +google.com mail is handled by 20 alt1.aspmx.l.google.com.
 +google.com mail is handled by 10 aspmx.l.google.com.
 +google.com mail is handled by 40 alt3.aspmx.l.google.com.
 +</​code>​
 +
 +<​code>​
 +$ nslookup google.com
 +Server:​ 192.168.100.1
 +Address:​ 192.168.100.1#​53
 +
 +Non-authoritative answer:
 +Name:​ google.com
 +Address: 172.217.20.14
 +</​code>​
 +
 +Pentru aflarea unui nume pe baza unei adrese IP, se pot folosi tot //host// sau //​nslookup//:​
 +
 +<​code>​
 +$ host 8.8.8.8
 +8.8.8.8.in-addr.arpa domain name pointer dns.google.
 +</​code>​
 +
 +<​code>​
 +$ nslookup 8.8.8.8
 +8.8.8.8.in-addr.arpa name = dns.google.
 +
 +Authoritative answers can be found from:
 +in-addr.arpa nameserver = a.in-addr-servers.arpa.
 +in-addr.arpa nameserver = b.in-addr-servers.arpa.
 +in-addr.arpa nameserver = c.in-addr-servers.arpa.
 +in-addr.arpa nameserver = e.in-addr-servers.arpa.
 +in-addr.arpa nameserver = d.in-addr-servers.arpa.
 +in-addr.arpa nameserver = f.in-addr-servers.arpa.
 +</​code>​
 +
 +Un exemplu de output //tcpdump// pentru comanda //host// este mai jos (unde 53 este portul implicit pentru DNS):
 +
 +<​code>​
 +$ sudo tcpdump port 53
 +tcpdump: data link type PKTAP
 +tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
 +listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
 +
 +08:​12:​17.446368 IP 192.168.100.4.63991 > 192.168.100.1.domain:​ 31461+ A? google.com. (28)
 +08:​12:​17.450412 IP 192.168.100.1.domain > 192.168.100.4.63991:​ 31461 1/0/0 A 172.217.16.110 (44)
 +08:​12:​18.455598 IP 192.168.100.4.58146 > 192.168.100.1.domain:​ 4039+ AAAA? google.com. (28)
 +08:​12:​18.463761 IP 192.168.100.1.domain > 192.168.100.4.58146:​ 4039 1/0/0 AAAA 2a00:​1450:​400d:​803::​200e (56)
 +08:​12:​19.467330 IP 192.168.100.4.53016 > 192.168.100.1.domain:​ 58519+ MX? google.com. (28)
 +08:​12:​19.514778 IP 192.168.100.1.domain > 192.168.100.4.53016:​ 58519 5/0/0 MX alt3.aspmx.l.google.com. 40,
 +MX alt4.aspmx.l.google.com. 50, MX aspmx.l.google.com. 10, MX alt1.aspmx.l.google.com. 20,
 +MX alt2.aspmx.l.google.com. 30 (136)
 +</​code>​
 +
  
 === Utilitarul dig === === Utilitarul dig ===
Line 427: Line 446:
 ;; global options: +cmd ;; global options: +cmd
 8.8.8.8.in-addr.arpa. 17648 IN PTR dns.google. 8.8.8.8.in-addr.arpa. 17648 IN PTR dns.google.
 +</​code>​
 +
 +
 +
 +
 +
 +==== E-mail ====
 +
 +Un mesaj e-mail a fost întotdeauna transmis în format plain-text (text clar). Chiar si prin adăugarea atașamentelor,​ mesajele de e-mail sunt trimise tot ca mesaje plain-text, prin folosirea unor mecanisme de codificare (//​uuencode/​uudecode//,​ //​MIME/​BASE64//​).
 +
 +Un mesaj este format dintr-o secțiune de antete (headers), urmată de o secțiune cu conținutul mesajului. Structura antetelor este descrisă în [[https://​tools.ietf.org/​html/​rfc822|RFC 822]], [[https://​tools.ietf.org/​html/​rfc1521|RFC 1521]] și [[https://​tools.ietf.org/​html/​rfc1806|RFC 1806]], ele având în general următoarea structură:
 +
 +  * unul sau mai multe antete //​Received//,​ care indică ce cale a fost urmată de mesaj de la sursa până la destinație
 +  * //​Mime-Version//:​ versiunea MIME (Multipurpose Internet Mail Extensions) folosită, 1.0 in general
 +  * //​Content-Type//:​ //​text/​plain//​ pentru mesaje text, //​multipart/​mixed//​ pentru mesaje cu atașamente
 +  * //​Subject//:​ subiectul mesajului
 +  * //Date//: data și ora când a fost trimis mesajul
 +  * //Message ID//: un ID pentru mesaj, folosit pentru identificarea în mod unic a unui mesaj
 +  * //From//: numele și adresa de mail a expeditorului
 +  * //To//: numele și adresa de mail a destinatarului
 +  * //Cc//: carbon copy (alți destinatari)
 +  * alte antete introduse de clientul de e-mail folosit pentru a trimite mesajul.
 +
 +Conținutul mesajului este textul propriu-zis,​ pentru mesajele în text clar fără atașamente. Se poate observa mai jos un exemplu de mesaj:
 +
 +<​code>​
 +MIME-Version:​ 1.0
 +From: profesor@upb.ro
 +To: student@upb.ro
 +Subject: Tema
 +Content-Type:​ text/plain
 +
 +Draga student,
 +
 +Fa-ti tema!
 +
 +Cu bine,
 +Profesorul.
 +</​code>​
 +
 +Mesajele cu atașamente pot folosi una din următoarele tehnici pentru codificarea acestora:
 +
 +  * //​uuencode//​ - la începuturile e-mail-ului,​ fișierele care se doreau trimise ​ trebuiau convertite în format text și invers prin folosirea utilitarelor numite //​uuencode/​uudecode//;​ și în ziua de azi, unii clienți de mail adaugă atașamentele la sfârșitul mesajelor, codificându-le cu algoritmul folosit de //​uuencode//​
 +  * //​MIME/​Base64//​ - această tehnologie este cea recomandată pentru trimiterea de mesaje cu atașamente.
 +
 +Un mesaj cu atașamente codificate [[https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Basics_of_HTTP/​MIME_types|MIME]] arată în felul următor:
 +
 +<​code>​
 +MIME-Version:​ 1.0
 +From: Student Studentescu <​student@upb.ro>​
 +To: Profesor PC <​profesor@upb.ro>​
 +Subject: Re: Tema
 +Content-Type:​ multipart/​mixed;​ boundary=abc
 +
 +--abc
 +Content-Type:​ text/plain
 +
 +Atasez tema.
 +
 +Cu bine,
 +Studentul
 +
 +--abc
 +Content-Type:​ text/plain
 +Content-Disposition:​ attachment; filename="​tema.c"​
 +
 +#include <​stdio.h>​
 +int main()
 +{
 +    printf("​Aceasta este tema mea\n"​);​
 +    return 0;
 +}
 +--abc
 +</​code>​
 +
 +Se observă faptul că părțile care compun mesajul sunt separate între ele printr-un șir de caractere separator (boundary string), specificat ca un parametru pentru antetul //​Content-Type//​. Fiecare parte poate avea la rândul ei propriile antete, care conțin în general tipul și numele fișierului din secțiunea respectivă. În cazul în care se trimit atașamente binare, acestea sunt codificate folosind schema numită Base64, descrisă în [[https://​tools.ietf.org/​html/​rfc1521|RFC 1521]].
 +
 +
 +==== Protocoalele SMTP, POP3 și IMAP ====
 +
 +În terminologia folosită de sistemele de e-mail, există trei actori. Aceștia pot fi situați pe trei mașini diferite sau pot co-exista pe aceeași gazdă:
 +
 +  - Mail User Agent (MUA) - aplicația folosită de utilizator pentru a citi și trimite mesaje e-mail (clientul de e-mail); el nu primește direct mesaje, acesta fiind rolul Mailbox Server-ului
 +  - Mailbox Server - serverul care primește și stochează mesajele (server de e-mail)
 +  - Mail Transfer Agent (MTA) - aplicația care primește și retrimite mesajele spre un alt MTA sau spre un Mailbox Server (“router” de e-mail).
 +
 +=== SMTP ===
 +
 +SMTP (Simple Mail Transfer Protocol) este un protocol care se folosește pentru trimiterea mesajelor electronice (de la un client către un server). Acesta se foloseste de portul 25 peste TCP și este descris în [[https://​tools.ietf.org/​html/​rfc821|RFC 821]] și [[https://​tools.ietf.org/​html/​rfc5321|RFC 5321]].
 +
 +Mesajele necesare în SMTP pentru trimiterea unui e-mail sunt următoarele:​
 +
 +<​code>​
 +1: HELO client.upb.ro
 +2: MAIL FROM: <​profesor@upb.ro>​
 +3: RCPT TO: <​student@upb.ro>​
 +4: DATA
 +5: MIME-Version:​ 1.0
 +From: profesor@upb.ro
 +To: student@upb.ro
 +Subject: Tema
 +Content-Type:​ text/plain
 +
 +Draga student,
 +  ​
 +Fa-ti tema!
 +   
 +Cu bine,
 +Profesorul.
 +.
 +6: QUIT
 +</​code>​
 +
 +Se trimite deci întâi o comandă "​HELO"​ cu numele de domeniu sau adresa IP a clientului pentru a iniția sesiunea, apoi o comandă "MAIL FROM" cu adresa sursei, "RCPT TO" pentru destinație,​ "​DATA"​ pentru date (e-mail-ul în sine) și "​QUIT"​ pentru a se închide sesiunea. Secțiunea de date trebuie neapărat terminată cu secvența de caractere ''​%%<​CR><​LF>​.<​CR><​LF>​%%''​ (adică o linie nouă urmată de un punct și apoi de încă o linie nouă).
 +
 +Găsiți mai jos modul implmentare in C a unui mesaj SMTP.
 +
 +<​spoiler>​
 +void create_mail(char *buffer, char* filename)
 +{
 +    int size = 500;
 +    int ret, fd;
 +    char filebuf[500];​
 +    ​
 +    size = write_string(buffer + MAXLEN - size, size, "​MIME-Version:​ 1.0\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "From: sender@mail.com\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "To: receiver@mail.com\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​Subject:​ Mail\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​Content-Type:​ multipart/​mixed;​ boundary=xxx\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​\r\n--xxx\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​Content-Type:​ text/​plain\r\n\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "This is the body of the e-mail.\r\nBest regards\r\n\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​--xxx\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​Content-Type:​ text/​plain\r\n"​);​
 +    size = write_string(buffer + MAXLEN - size, size, "​Content-Disposition:​ attachment; filename=\""​);​
 +    size = write_string(buffer + MAXLEN - size, size, filename);
 +    size = write_string(buffer + MAXLEN - size, size, "​\"​\r\n\r\n"​);​
 +
 +    //deschide fisier filename
 +    //citeste mesajul din fisier
 +    //inchide fisier
 +
 +    size = write_string(buffer + MAXLEN - size, size, "​\r\n--xxx\r\n."​);​
 +}
 +
 +</​spoiler>​
 +
 +=== POP3 ===
 +
 +POP3 (Post Office Protocol 3) este un protocol utilizat pentru citirea mesajelor electronice (de la un server către un client). Clientul va interoga periodic serverul, va descărca mesajele și le va șterge automat de pe server. Comunicația se realizează folosind portul 110 peste TCP, în felul următor:
 +
 +<​code>​
 +1: USERNAME username
 +2: PASS password
 +3: LIST
 +4: RETR 1
 +5: QUIT
 +</​code>​
 +
 +=== IMAP ===
 +
 +IMAP (Internet Message Access Protocol) este un protocol care se folosește pentru citirea mesajelor electronice (de la un server catre un client). Clientul interoghează periodic serverul și poate cere mesaje complete sau doar porțiuni (header, body), și nu va șterge automat mesajele de pe server. Comunicația se realizează prin TCP, folosind portul 143.
 +
 +<​code>​
 +1: LOGIN username password
 +2: LIST ""​ "​*"​
 +3: EXAMINE Inbox
 +4: FETCH 1 BODY[]
 +5: LOGOUT
 </​code>​ </​code>​
  
Line 432: Line 620:
 ==== Suportul de laborator ==== ==== Suportul de laborator ====
  
-===I. Email=== + 
-Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/Email|aici]] un cod sursă schelet pentru realizarea unui client de email SMTP scris in C. Veți folosi un server SMTP acre rulează local. Acesta poate fi creat folosind un utilitar existent în Python, numit //smtpd//. Rularea acestui utiliar pe portul 25 se face astfel:+===I. DNS=== 
 +Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​master/​lab11|aici]] un cod sursă schelet pentru realizarea unei aplicații in C care utilizează API-ul DNS 
 + 
 +===II. Email=== 
 +Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/-/​tree/​master/​lab11|aici]] un cod sursă schelet pentru realizarea unui client de email SMTP scris in C. Veți folosi un server SMTP acre rulează local. Acesta poate fi creat folosind un utilitar existent în Python, numit //smtpd//. Rularea acestui utiliar pe portul 25 se face astfel:
  
 <​code>​ <​code>​
Line 443: Line 635:
 </​note>​ </​note>​
  
-===II. DNS=== 
-Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/​dns|aici]] un cod sursă schelet pentru realizarea unei aplicații in C care utilizează API-ul DNS.  
  
  
 ==== Exerciții ==== ==== Exerciții ====
  
-===I. E-mail=== +===I. DNS===
-Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/​Email|aici]],​ implementați următoatrea cerință:+
  
-1. Implementați un client SMTP peste TCP prin care să trimiteți către serverul //smtpd// un e-mail care conține niște text și un fișier dat ca parametru sub forma unui atașament de tip //​text/​plain//​ (API-ul necesar pentru conexiunea TCP cu server-ul este detaliat în [[https://​ocw.cs.pub.ro/​courses/​pc/​laboratoare/​07|laboratorul 7]]). +Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​master/​lab11|aici]], implementați următoatrea cerință:
- +
-== Bonus == +
- +
-  - Folosind instrucțiunile de [[https://​www.dropbox.com/​s/​d382g7f705uo6bq/​SMTP_Google.pdf?​dl=0|aici]],​ trimiteți un e-mail către asistent prin intermediul serverului SMTP de la Google. +
- +
-===II. DNS=== +
- +
-Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/dns|aici]], implementați următoatrea cerință:+
  
 1. Scrieți un program care să afișeze numele și adresele IP pentru un host. Programul poate primi ca parametru fie numele (caz în care se va afișa adresa), fie adresa IP (caz în care se va afișa numele). Testați-va programul folosind informațiile din tabelul de mai jos. Exemplu de apel: <​code>​ 1. Scrieți un program care să afișeze numele și adresele IP pentru un host. Programul poate primi ca parametru fie numele (caz în care se va afișa adresa), fie adresa IP (caz în care se va afișa numele). Testați-va programul folosind informațiile din tabelul de mai jos. Exemplu de apel: <​code>​
Line 468: Line 649:
 2. Folosind utilitarul //dig//, realizați următoarele sarcini: 2. Folosind utilitarul //dig//, realizați următoarele sarcini:
     - realizați cereri de adresă (A) pentru fiecare gazdă din tabelul de mai jos     - realizați cereri de adresă (A) pentru fiecare gazdă din tabelul de mai jos
-    - pentru gazdele care au (și) adrese IPv6, realizați cereri de tip AAAA 
     - pentru serverul de mail din tabelul de mai jos, realizați o cerere de tip MX     - pentru serverul de mail din tabelul de mai jos, realizați o cerere de tip MX
-    - realizați o cerere DNS în care să afișați doar secțiunea de RR-uri autoritare 
-    - folosiți mai multe servere de nume pentru a interoga adresa IP a //​google.com//​ (puteți găsi [[https://​public-dns.info|aici]] o listă de servere DNS publice); veți observa că nu întotdeauna primiți același IP; de ce?  ​ 
-    - realizați o interogare de tip //bulk// (folosind un fișier pentru definirea cererilor) la serverul de nume 8.8.8.8 pentru toate gazdele din tabelul de mai jos; fișierul folosit trebuie inclus în arhiva cu rezolvări 
- 
 Găsiți mai jos un tabel cu o serie de gazde și RR-urile asociate: Găsiți mai jos un tabel cu o serie de gazde și RR-urile asociate:
 <​spoiler>​ <​spoiler>​
 ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^ ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^
 |  **Pentru single-v4 există o singură adresă IPv4** ​                                                                  ||||| |  **Pentru single-v4 există o singură adresă IPv4** ​                                                                  |||||
-|  A      |  single-v4.protocoale.xyz   |  127.0.0.1 ​                       |  300                                         |+|  A      |  single-v4.protocoale.life   |  127.0.0.1 ​                       |  300                                         |
 |  **Pentru single-v4 există o singură adresă IPv6** ​                                                                  ||||| |  **Pentru single-v4 există o singură adresă IPv6** ​                                                                  |||||
-|  AAAA   ​| ​ single-v6.protocoale.xyz   |  ::1                              |  300                                         |+|  AAAA   ​| ​ single-v6.protocoale.life   |  ::1                              |  300                                         |
 |  ** Pentru single se definesc 2 adrese (una IPv4 si una IPv6)** ​                                                     ||||| |  ** Pentru single se definesc 2 adrese (una IPv4 si una IPv6)** ​                                                     |||||
-|  A      |  single.protocoale.xyz      ​| ​ 127.0.0.1 ​                       |  300                                         | +|  A      |  single.protocoale.life      ​| ​ 127.0.0.1 ​                       |  300                                         | 
-|  AAAA   ​| ​ single.protocoale.xyz      ​| ​ ::1                              |  300                                         | +|  AAAA   ​| ​ single.protocoale.life      ​| ​ ::1                              |  300                                         | 
-|  **Spațiul dorinel.protocoale.xyz este delegat către un alt server de nume ce rulează la adresa potato.dfilip.xyz** ​ ||||| +|  **Spațiul dorinel.protocoale.life este delegat către un alt server de nume ce rulează la adresa potato.dfilip.xyz** ​ ||||| 
-|  NS     ​| ​ dorinel.protocoale.xyz     |  potato.dfilip.xyz ​               |  300                                         |+|  NS     ​| ​ dorinel.protocoale.life     |  potato.dfilip.xyz ​               |  300                                         |
 |  **Pentru multi-v4 există 4 adrese IPv4** ​                                                                           ||||| |  **Pentru multi-v4 există 4 adrese IPv4** ​                                                                           |||||
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.1.1.1 ​                       |  300                                         | +|  A      |  multi-v4.protocoale.life    ​| ​ 127.1.1.1 ​                       |  300                                         | 
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.2.2.2 ​                       |  300                                         | +|  A      |  multi-v4.protocoale.life    ​| ​ 127.2.2.2 ​                       |  300                                         | 
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.3.3.3 ​                       |  300                                         | +|  A      |  multi-v4.protocoale.life    ​| ​ 127.3.3.3 ​                       |  300                                         | 
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.4.4.4 ​                       |  300                                         |+|  A      |  multi-v4.protocoale.life    ​| ​ 127.4.4.4 ​                       |  300                                         |
 |  **Pentru multi-v6 există 4 adrese IPv6** ​                                                                           ||||| |  **Pentru multi-v6 există 4 adrese IPv6** ​                                                                           |||||
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::1                              |  300                                         | +|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::1                              |  300                                         | 
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::2                              |  300                                         | +|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::2                              |  300                                         | 
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::3                              |  300                                         | +|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::3                              |  300                                         | 
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::4                              |  300                                         |+|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::4                              |  300                                         |
 |  **Pentru multi se definesc 8 adrese (4 de IPv4 și 4 de IPv6)** ​                                                     ||||| |  **Pentru multi se definesc 8 adrese (4 de IPv4 și 4 de IPv6)** ​                                                     |||||
-|  A      |  multi.protocoale.xyz       |  127.1.1.1 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.1.1.1 ​                       |  300                                         | 
-|  A      |  multi.protocoale.xyz       |  127.2.2.2 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.2.2.2 ​                       |  300                                         | 
-|  A      |  multi.protocoale.xyz       |  127.3.3.3 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.3.3.3 ​                       |  300                                         | 
-|  A      |  multi.protocoale.xyz       |  127.4.4.4 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.4.4.4 ​                       |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::1                              |  300                                         | +|  AAAA   ​| ​ multi.protocoale.life       |  ::1                              |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::2                              |  300                                         | +|  AAAA   ​| ​ multi.protocoale.life       |  ::2                              |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::3                              |  300                                         | +|  AAAA   ​| ​ multi.protocoale.life       |  ::3                              |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::4                              |  300                                         ​|  ​+|  AAAA   ​| ​ multi.protocoale.life       |  ::4                              |  300                                         ​|  ​
 |  **Adresele pc->​pcom->​protocoale definesc un șir de nume canonice care are la capăt o adresă IPv4** ​                 ||||| |  **Adresele pc->​pcom->​protocoale definesc un șir de nume canonice care are la capăt o adresă IPv4** ​                 |||||
-|  CNAME  |  pc.protocoale.xyz          ​| ​ pcom.protocoale.xyz              ​| ​ 300                                         | +|  CNAME  |  pc.protocoale.life          ​| ​ pcom.protocoale.life              ​| ​ 300                                         | 
-|  CNAME  |  pcom.protocoale.xyz        ​| ​ protocoale.protocoale.xyz        ​| ​ 300                                         | +|  CNAME  |  pcom.protocoale.life        ​| ​ protocoale.protocoale.life        ​| ​ 300                                         | 
-|  A      |  protocoale.protocoale.xyz  ​| ​ 127.42.42.42 ​                    ​| ​ 300                                         |+|  A      |  protocoale.protocoale.life  ​| ​ 127.42.42.42 ​                    ​| ​ 300                                         |
 |  **Emailul este deservit de 3 servere SMTP cu priorități diferite** ​                                                 ||||| |  **Emailul este deservit de 3 servere SMTP cu priorități diferite** ​                                                 |||||
-|  MX     ​| ​ protocoale.xyz             |  alt1.gmail-smtp-in.l.google.com ​ |  300  |  10                                  | +|  MX     ​| ​ protocoale.life             |  alt1.gmail-smtp-in.l.google.com ​ |  300  |  10                                  | 
-|  MX     ​| ​ protocoale.xyz             |  alt2.gmail-smtp-in.l.google.com ​ |  300  |  20                                  | +|  MX     ​| ​ protocoale.life             |  alt2.gmail-smtp-in.l.google.com ​ |  300  |  20                                  | 
-|  MX     ​| ​ protocoale.xyz             |  alt3.gmail-smtp-in.l.google.com ​ |  300  |  30                                  |+|  MX     ​| ​ protocoale.life             |  alt3.gmail-smtp-in.l.google.com ​ |  300  |  30                                  |
 ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^ ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^
 </​spoiler>​ </​spoiler>​
  
  
 +===II. E-mail===
 +Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​master/​lab11|aici]],​ implementați următoatrea cerință:
 +
 +1. Implementați un client SMTP peste TCP prin care să trimiteți către serverul //smtpd// un e-mail care conține niște text și un fișier dat ca parametru sub forma unui atașament de tip //​text/​plain//​ (API-ul necesar pentru conexiunea TCP cu server-ul este detaliat în [[https://​ocw.cs.pub.ro/​courses/​pc/​laboratoare/​07|laboratorul 7]]).
 +
 +== Bonus ==
 +
 +  - Folosind instrucțiunile de [[https://​www.dropbox.com/​s/​d382g7f705uo6bq/​SMTP_Google.pdf?​dl=0|aici]],​ trimiteți un e-mail către asistent prin intermediul serverului SMTP de la Google.
pc/laboratoare/11.1652483321.txt.gz · Last modified: 2022/05/14 02:08 by bogdan_costel.mocanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0