Table des matières
Références globales :
- CNP3, chap. # Electronic mail
3.4. Le courrier électronique
Le courrier électronique est apparu dans les années 70. A l’origine, il s’agissait de s’échanger de courts messages texte, mais avec le temps, le format s’est adapté aux usages, et permet à présent l’échange de courrier contenant des média de différents types, grâce à l’extension MIME.
Les deux éléments principaux du courrier électronique sont son format, qui doit être défini et standardisé afin de pouvoir être lu par des clients et manipulés par des serveurs, et son protocole principal, SMTP, qui permet le transfert d’email.
Contrairement au web, les échanges de mail ne se font pas nécessairement un client et un serveur unique. Il y aura en général plusieurs interlocuteurs dans un tel échange. De plus, comme le destinataire d’un message n’est pas une machine mais un humain qui n’est, en théorie, pas connecté 24h/24, il va aussi falloir prévoir un mécanisme de stockage du message en attendant sa consultation (“boîte mail”), ainsi qu’un système de récupération du message sur la boîte mail, service qui peut être fourni par le protocole POP ou le protocole IMAP.
L’ensemble de l’architecture de messagerie Internet est décrite dans le RFC 5598
Format d’un message électronique
En-tête et corps du message
Le courrier électronique a été conçu de manière similaire au courrier postal. Dans ce dernier, le message à transmettre est “emballé” dans une enveloppe, qui renseigne, d’un côté, le nom et l’adresse du destinataire, et de l’autre, sur le rabat, le nom et l’adresse de l’expéditeur.
Dans le courrier électronique, ces informations seront également ajoutées au message principal, sous la forme d’un en-tête. Cet entête contiendra différents champs dont, entre autres :
- (obligatoire) l’adresse email de l’expéditeur, entre
<
et>
, éventuellement accompagnée de son nom, - (obligatoire) la date de l’expédition,
- l’adresse email du ou des destinataires, entre
<
et>
, éventuellement accompagnés de leurs noms, - le sujet de l’email
Pour indiquer la fin de la section d’en-tête, il faut insérer une ligne vide, contenant uniquement les caractères de fin de ligne <CR>
et <LF>
. Après l’en-tête vient le corps du message. Dans les premières années du courrier électronique, seuls les caractères ASCII-US (code 0 à 127) étaient autorisés dans un message. Cela a bien entendu évolué par après, comme nous le verrons plus loin.
Voici un exemple de courrier électronique très simple, destiné à être reçu par deux personnes :
From: Bob Smith <Bob@machine.example>
To: Alice Doe <alice@example.net>, Alice Smith <Alice@machine.example>
Subject: Hello
Date: Mon, 8 Mar 2010 19:55:06 -0600
Ceci est un message mail
Ceci est la seconde ligne du corps du message.
Les messages mail peuvent avoir des en-têtes beaucoup plus fournis, comme le montre l’exemple ci-dessous, généré par ChatGPT :
Return-Path: <john.doe@example.com>
Received: from mail.example.com (mail.example.com [192.0.2.1]) by mx.google.com with ESMTPS id a1b2c3d4e5f6g7h8i9 for <jane.smith@example.com>; Thu, 30 Nov 2024 10:30:00+0100 (CET)
Received: from localhost (localhost [127.0.0.1]) by mail.example.com (Postfix) with ESMTP id 1234ABCD5678 for <jane.smith@example.com>; Thu, 30 Nov 2024 10:29:55 +0100 (CET)
Received: from user-laptop (192.168.1.100) by mail.example.com (Postfix) with ESMTPA id 5678EFGH1234 for <jane.smith@example.com>; Thu, 30 Nov 2024 10:29:50 +0100 (CET)
From: John Doe <john.doe@example.com>
To: Jane Smith <jane.smith@example.com>
Cc: team@example.com
Subject: Réunion de projet prévue
Date: Thu, 30 Nov 202410:29:50 +0100
Message-ID: <abc1234567890def@example.com>
Reply-To: john.doe@example.com
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="boundary-example"
X-Mailer: CustomMailer/1.0
[Corps du message supprimé]
On retrouve dans cet exemple les quatre champs d’en-tête déjà montrés, avec en plus des indications sur :
- le fait que ce message est une réponse à un message précédent. Cette relation est possible grâce à l’utilisation du champ
Message-id
- les serveurs par lesquels le message a transité, avec des informations sur leurs noms DNS, leurs IP, et le logiciel utilisé.
Plus d’informations sur les en-têtes des courriers électroniques peuvent être trouvés dans les RFC5321 et RFC5322(https://datatracker.ietf.org/doc/html/rfc5322.html#section-2.2).
MIME
L’usage du courrier électronique a bien évolué depuis sa création. Alors qu’au départ, il ne véhiculait que des messages en ASCII-us, il permet à présent d’utiliser n’importe quel ensemble de caractères, et il est également possible de joindre des documents de toutes sortes en pièces jointes. Cela est possible grâce au standard MIME (Multi-purpose Internet Mail Extensions), qui a été créé pour fournir des extensions au format de base du courrier électronique. Le standard MIME a depuis été repris dans d’autres usages, comme par exemple dans le protocole HTTP pour définir le format des fichiers échangés sur le web.
MIME définit un ensemble de champs d’en-têtes supplémentaires et optionnels, dont notamment :
MIME-Version:
la présence de cet en-tête indique que le contenu du message est formaté avec MIME. La valeur du champ sera typiquement1.0
.Content-Type:
Bien connu, ce champ indique le type du contenu qui suit. Ses valeurs ont deux parties : un type et un sous-type.- Vous connaissez sans doute
text/plain
ou encoretext/hmtl
, ouimg/png
. Notez que dans le cas de données textuelles, l’encodage peut être précisé par l’attributcharset
. Par exemple :Content-Type: text/plain; charset=utf-8
- Il existe également un type particulier,
multipart
, qui indique un contenu en plusieurs parties. Il peut avoir différents sous-types, dont notamment :multipart/mixed
, qui indique des parties de types différents. C’est le cas par exemple d’un email qui possède un contenu principal textuel et une pièce jointe sous format PDF. Il faudra définir un élément frontière permettant de séparer les différentes parties. Cet élément est renseigné par l’attributboundary=
.multipart/alternative
, qui indique que, pour un contenu, il existe plusieurs versions de format différent. C’est par exemple utile si un message est envoyé à la fois en version texte et en version html, permettant au destinataire de choisir le format le plus adapté en fonction du logiciel de lecture utilisé.
- Vous connaissez sans doute
Voici un exemple de courrier électronique généré par ChatGPT illustrants l’usage de MIME pour les contenus alternatifs et les pièces jointes :
From: exemple@domaine.com
To: destinataire@domaine.com
Subject: Exemple d'email multipart avec pièce jointe
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="boundary-mixed"
--boundary-mixed
Content-Type: multipart/alternative; boundary="boundary-alternative"
--boundary-alternative
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Bonjour,
Ceci est un exemple d'email avec une partie texte (brut et html) ainsi qu'une pièce jointe.
--boundary-alternative
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: 7bit
<html>
<body>
<p>Bonjour,</p>
<p>Ceci est un exemple d'email avec une partie texte (brut et <strong>html</strong>) ainsi qu'une pièce jointe.</p>
</body>
</html>
--boundary-alternative--
--boundary-mixed
Content-Type: application/pdf
Content-Disposition: attachment; filename="exemple.pdf"
Content-Transfer-Encoding: base64
JVBERi0xLjUKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwvTGluZWFyaXplZCAxL0wgMTEyMTIvTiAxL1R5
cGUgL0NhdGFsb2cvUGFnZXMgNSAwIFI+PgplbmRvYmoKNiAwIG9iago8PC9Db250ZW50cyA3IDAgUi9U
eXBlIC9QYWdlPj4KZW5kb2JqCjcgMCBvYmoKPDwvTGVuZ3RoIDEzPj4Kc3RyZWFtCkJUWCBXZWxjb21l
IHRvIHRoZSB3b3JsZCBvZiBQSURGCmVuZHN0cmVhbQplbmRvYmoK...
--boundary-mixed--
Nous pouvons observer les différentes parties de cet email :
- l’en-tête principal, avec la version de MIME annonçant un contenu MIME, ainsi que le
Content-Type
principalmultipart/mixed
annonçant que le corps du message présente plusieurs parties. Ces parties seront séparées par la frontièreboundary-mixed
. - La première partie du corps du message est elle-même de type
multipart
, cette fois avec le sous-typealternative
. Elle contient deux sous-parties séparées par la frontièreboundary-alternative
, une contenant le message en texte simple et l’autre en HTML. Le logiciel destinataire pourra choisir l’une ou l’autre des versions disponibles. - La seconde partie est la pièce jointe, de type
application/pdf
. Un autre champ MIMEContent-Disposition
permet d’ajouter des informations sur la pièce jointe, dont notamment son nom de fichier.
Etapes d’un échange d’email
Un message de courrier électronique est typiquement consulté ou rédigé par l’utilisateur sur un logiciel dédié, un client mail. Dans la terminologie technique, ce logiciel est appelé un Mail User Agent, ou MUA. Il sert d’interface avec le système de messagerie. En général, les MUA sont des clients lourds, bien qu’à l’heure actuelle, beaucoup d’utilisateurs leurs préfèrent les versions “Webmail”.
Pour pouvoir envoyer des courriers, ce logiciel va s’adresser à d’autres agents du système, les Mail Transfert Agents, ou MTA. Ce sont des logiciels serveurs qui s’occupent de relayer les emails qu’ils reçoivent jusqu’à leur destination finale, la boîte mail ou mailbox du destinataire hébergée sur le serveur auquel ce dernier est rattaché. Cette boîte mail peut être, selon le format utilisé par le logiciel , un fichier dans lesquels les messages sont concaténés (format mbox), ou un répertoire qui contient un fichier par mail (format Maildir).
En général, chaque domaine fournissant un service de courrier électronique possèdera un ou plusieurs MTAs. Le Resource Record MX du domaine permet d’annoncer le ou les serveurs MTAs du domaine.
Pour envoyer un courrier, un MUA contactera d’abord le serveur du service mail employé par l’utilisateur, et ce dernier s’occuperai de relayer le courrier vers le MTA du destinataire. Le protocole utilisé dans ce cadre est le SMTP (Simple Mail Transfert Protocol).
Les utilisateurs n’étant pas nécessairement connectés en permanence, les messages sont en général stockés sur le serveur mail, dans la mailbox. Pour les consulter, les MUAs vont utiliser un protocole de récupération de mail. Deux protocoles de ce type existent :
- POP (Post Office Protocol) : permet de récupérer les mails sur le serveur. POP est à la base conçu pour récupérer les mails et les conserver sur le poste client. Ils sont donc par défaut supprimés du serveur. Ce protocole est moins utilisé actuellement car les utilisateurs ont plusieurs terminaux, et ne souhaitent pas voir leurs messages répartis entre ces derniers. Un stockage sur le serveur sera alors plus pratique.
- IMAP (Internet Message Access Protocol) : est conçu pour permettre la consultation des messages tout en gardant ceux-ci sur le serveur. Ce système est donc plus pratique pour centraliser la gestion des emails sur le serveur.
Illustration d’un échange mail
Dans l’image ci-dessous, Alice souhaite envoyer un mail à Bob. Tous les deux utilisent un service mail différent. Alice utilise le service mail du domaine a.net
et Bob celui du domaine b.net
. Les étapes de l’échange sont les suivantes :
- Alice rédige son mail sur son logiciel MUA. Lorsqu’elle déclenche l’envoi, le MUA contacte le MTA du domaine et lui transfère le mail en SMTP.
- Le serveur mail du domaine
a.net
, à la réception du message, comprend sur base de l’adresse qu’il doit le relayer vers le domaineb.net
. Pour cela, il a besoin de l’adresse IP d’un serveur mail de ce domaine. Il va utiliser le DNS pour cela, en envoyant d’abord une requête de typeMX
pour obtenir le nom du ou des serveurs mail deb.net
. Ensuite, il enverra une requête de typeA
pour obtenir l’adresse IP correspondant au nom du serveur qu’il souhaite contacter. - Le mail est relayé depuis le serveur de
a.net
vers le serveur deb.net
, toujours en utilisant le protocole SMTP. - A la réception du courrier, le serveur de
b.net
identifie, grâce à l’adresse email, que le message est arrivé à destination. Il va donc, sur base de la partie “utilisateur” de l’adresse mail, retrouver la mailbox dans laquelle il doit stocker le message. - Lorsque Bob se connecte à son tour à son MUA, ce dernier va établir une connexion avec le serveur mail de son domaine, pour aller consulter sa boîte mail. Pour cette étape, le logiciel n’utilise pas le protocole de transfert de mail SMTP, mais un protocole de récupération d’email. Dans ce cas, il s’agit d’IMAP.
Protocoles
Les protocoles mail, comme beaucoup de protocoles applicatifs, utilisent des commandes textuelles, ce qui les rend relativement lisible pour les humains.
Ils fonctionnent, tout comme HTTP, selon l’architecture Client/Serveur : le serveur reste à l’écoute des requêtes des clients et y répond lorsque ces derniers s’adressent à lui.
Comme il s’agit de transfert de messages textuels non instantanés, le protocole transport utilisé sera logiquement TCP, pour garantir la fiabilité des échanges.
Actuellement, les échanges de mail seront sécurisés via l’encapsulation dans une couche de chiffrement TLS. Nous verrons cela plus précisément au second semestre.
SMTP
Le protocole SMTP (Simple Mail Transport Protocol), défini dans le RFC 5321 se charge donc d’acheminer le courrier depuis un MUA vers un MTA, puis de MTA en MTA jusqu’à l’arrivée sur le serveur de destination.
Comme il s’agit d’un transfert de données sans contrainte “temps-réel”, il fonctionnera logiquement par dessus le service transport fiable fournit par TCP. Le port standard qui lui est réservé est le port 25. Notez que, dans ses versions sécurisées, SMTP peut utiliser d’autres ports, nous verrons cela au second semestre.
SMTP travaille par échange de commandes/réponses, comme une conversation.
- Une commande est composée d’une ligne ASCII suivie des caractères de fin de ligne
<CR><LF>
. Certaines commandes seront suivies de transfert de données (typiquement, un email). Les commandes principales sont :HELO:/EHLO: <client name or IP>
: Initialisation de l’échange, où le client s’identifie auprès du serveur. La seconde version, indispensable dans les environnements modernes, permet la négociation de certaines extensions SMTP.MAIL FROM: <src mail address>
indique que le début de l’envoi d’un email, avec la spécification de l’expéditeurRCPT TO: <dst mail address>
Permet d’indiquer un destinataire. Elle peut être répétée plusieurs fois.DATA
: indique le début de l’envoi du courrier par le client. Pour signaler que cet envoi est terminé, le client devra envoyer une ligne composée d’un point unique (séquence<CR><LF>.<CR><LF>
)QUIT
: Signale la fin de l’envoi des emails et donc la conversation SMTP. Cette commande aura pour effet d’initier la terminaison de connexion TCP.- D’autres commandes existent, notamment à des fins de debugging, comme par exemple
VRFY
pour vérifier une adresse email, ouEXPN
pour valider une adresse de mailing list.
- Une réponse aura un code de réponse, avec un commentaire optionnel. Tout comme dans HTTP, le premier chiffre identifie le type de réponse.
- 2XX signifie une réponse positive.
- 3XX signifie que la commande est acceptée, mais que le traitement est en attende d’informations supplémentaires.
- 4XX signale que la commande n’a pas été acceptée, mais que le problème est plutôt temporaire et que la commande pourrait être acceptée ultérieurement.
- 5XX signale un problème “permanent”, indiquant que la commande ne doit pas être répétée telle qu’elle.
Voici un exemple d’échange SMTP tel qu’on pourrait le voir sur une trace Wireshark, ou qu’on pourrait effectuer grâce à la commande telnet
.
Lorsque la connexion TCP est établie, c’est-à-dire que le serveur a reçu le ACK du 3-Way Handshake, il répond avec une première réponse SMTP 220, indiquant que le serveur est prêt.
Le client effectue à son tour sa “salutation”, via le message EHLO. Dans ce cas, le client est la machine de nom mta.example.com
. Ce “client” est en pratique un serveur MTA, mais sera considéré comme client ici car il est l’initiateur de la connexion TCP et est celui qui souhaite transférer des messages.
Après les échanges initiaux, débute le transfert d’un ou plusieurs messages (un seul dans ce cas-ci). Celui-ci est en deux parties :
- L’échange des informations concernant l’expéditeur et le (ou les) destinataire(s) (un seul dans ce cas-ci).
- Le transfert de données proprement dites. On retrouve ici le format d’un message email vu plus haut, avec les en-têtes et le corps du message. Le message ici est du texte brut, mais on aurait pu utiliser le format MIME. Notez que le message est suivi d’une ligne contenant uniquement un point. Cette ligne signale la fin du transfert de ce message. Le client pourrait, à ce stade, choisir d’envoyer un mail supplémentaire, ce qu’il ne fait pas.
Enfin, la conversation se termine simplement avec la commande QUIT
.
# Début de la conversation SMTP
S: 220 smtp.example.com ESMTP MTA information
C: EHLO mta.example.org
S: 250 Hello mta.example.org, glad to meet you
# Déclenchement du transfert d'un message
C: MAIL FROM:<[alice@example.org](mailto:alice@example.org)>
S: 250 Ok
C: RCPT TO:<[bob@example.com](mailto:bob@example.com)>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
# Transfert du message proprement dit
C: From: "Alice Doe" <[alice@example.org (mailto:alice@example.org)>
C: To: Bob Smith <[bob@example.com](mailto:bob@example.com)>
C: Date: Mon, 9 Mar 2010 18:22:32 +0100
C: Subject: Hello
C:
C: Hello Bob
C: Ceci est un message contenant 4 lignes de textes.
C: Bien à toi,
C: Alice
C: .
S: 250 Ok: queued as 12345
# Fin de la conversation SMTP
C: QUIT
S: 221 Bye
Vous pouvez trouver un autre exemple de conversation SMTP sous forme de trace réseau, sur le site de Wireshark. Ce second exemple contient un message au format MIME, avec une pièce jointe : affichez l’échange applicatif avec “Follow TCP Stream” après avoir observé la conversation TCP, et n’hésitez pas à analyser le message MIME pour identifier les points présentés en début de ce chapitre.
IMAP/POP
Une fois le mail arrivé à destination dans la boîte mail du destinataire, il y est stocké jusqu’à ce que l’utilisateur souhaite relever son courrier. Pour cela, il faut utiliser un protocole de récupération d’email. Deux protocoles existent :
- POP (Post Office Protocol) : orienté téléchargement de messages, en conservant les messages préférentiellement sur le poste client.
- IMAP (Internet Message Access Protocol) : destiné à faire de la consultation de messages, en gardant les messages par défaut sur le serveur.
Avec l’évolution des usages et l’utilisation de terminaux multiples, il n’est en général plus très pratique à l’heure actuelle de télécharger les messages depuis le serveur et de les stocker sur un ordinateur donné. Les utilisateurs vont plutôt conserver leurs messages sur le serveur, et les consulter depuis divers terminaux (PC fixes, mobiles, smartphones, …). POP est donc moins utilisé actuellement, au profit d’IMAP.
Notez aussi que l’usage des clients dit “lourds”, à savoir des logiciels dédiés au courrier électroniques (ex : Thunderbird, Apple Mail, …) se raréfie au profit de la consultation des emails via des interfaces Web proposant de plus en plus de fonctionnalités (ex : GMail, Outlook365, …).
POP et IMAP travaillent, comme SMTP et pour les mêmes raisons, par dessus TCP. Le premier utilisait initialement le port 110 et le second le port 143 dans leurs versions non sécurisées. Nous verrons leurs versions sécurisées au second semestre.
Toujours comme SMTP, POP et IMAP travaillent via des échanges de commandes textuelles. Voici, à titre d’information, un exemple d’échange IMAP généré par ChatGPT. On voit que chaque commande commence par un code, suivi de la commande. Le serveur répond également par le même code, suivi d’un commentaire.
Quatre étapes sont illustrées dans cet extrait :
- l’authentification (notez le mot de passe en clair, pratique à bannir aujourd’hui),
- la consultation de l’état de la boîte mail,
- la récupération de l’en-tête du premier message et le marquage de ce dernier comme “lu”,
- la fin de la conversation.
C: A001 LOGIN username@example.com password123
S: A001 OK LOGIN completed
C: A002 SELECT INBOX
S: * 5 EXISTS
S: * 2 RECENT
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: A002 OK [READ-WRITE] SELECT completed
C: A003 FETCH 1 (FLAGS BODY[HEADER])
S: * 1 FETCH (FLAGS (\Seen) BODY[HEADER] {342}
From: sender@example.com
To: username@example.com
Subject: Test Email
Date: Mon, 4 Dec 2023 10:30:00 +0000
)
S: A003 OK FETCH completed
C: A004 LOGOUT
S: * BYE IMAP server signing off
S: A004 OK LOGOUT completed
Contrairement à POP qui est très efficace pour transférer les messages mais ne permet pas de gestion fine de ces derniers sur le serveur, IMAP offre des fonctionnalités de classement et de traitement des messages dans la mailbox elle-même :
- différents dossiers sur le serveur,
- plusieurs statuts possibles pour les messages (lus ou non, marqués, etc. ),
- recherche possible dans la mailbox,
- etc.
Vous pouvez trouver ici deux exemples de conversation telnet
illustrant POP et IMAP.
N’hésitez pas non plus à analyser les traces réseaux fournies sur le site de Wireshark. Utilisez l’option “Follow TCP Stream” pour afficher uniquement le contenu applicatif, une fois que vous avez étudié l’échange TCP.