Les commandes d'IMAP

Entrons maintenant qans le vif du sujet. Il y a quelques RFCs qui définissent IMAP4 tel qu'il est utilisé actuellement. Les voici :

RFCTitreCommentaire
2060INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1Pour mémoire
2087IMAP4 QUOTA extension
3501INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1Obsoletes: 2060
3502Internet Message Access Protocol (IMAP) - MULTIAPPEND Extension
3691Internet Message Access Protocol (IMAP) UNSELECT command
4314IMAP4 Access Control List (ACL) Extension
4315Internet Message Access Protocol (IMAP) - UIDPLUS extension
4466Collected Extensions to IMAP4 ABNF Updates: 2088, 2342, 3501, 3502, 3516
4469Internet Message Access Protocol (IMAP) CATENATE Extension Updates: 3501, 3502
4978The IMAP COMPRESS Extension
5032WITHIN Search Extension to the IMAP Protocol Updates: 3501

Et voici la liste des commandes, avec les RFC qui y font référence.

CommandeRFC
APPENDRFC 3501, RFC 3502, RFC 4466, RFC 4469
AUTHENTICATERFC 3501
CAPABILITYRFC 3501
CHECKRFC 3501
CLOSERFC 3501
COMPRESSRFC 4978
COPYRFC 3501
CREATERFC 3501, RFC 4466
DELETERFC 3501
DELETEACLRFC 4314
EXAMINERFC 3501, RFC 4466
EXPUNGERFC 3501
FETCHRFC 3501, RFC 4466
GETACLRFC 4314
GETQUOTARFC 2087
GETQUOTAROOTRFC 2087
LISTRFC 3501
LISTRIGHTSRFC 4314
LOGINRFC 3501
LOGOUTRFC 3501
LSUBRFC 3501
MYRIGHTSRFC 4314
NOOPRFC 3501
RENAMERFC 3501, RFC 4466
SEARCHRFC 3501, RFC 5032
SELECTRFC 3501, RFC 4466
SETACLRFC 4314
SETQUOTARFC 2087
STARTTLSRFC 3501
STATUSRFC 3501
STORERFC 3501, RFC 4466
SUBSCRIBERFC 3501
UIDRFC 3501, RFC 4315, RFC 4466
UNSELECTRFC 3691
UNSUBSCRIBERFC 3501
X<atom>RFC 3501

Au minimum, le RFC 3501 gagne à être lu pour mieux comprendre ce qui suit. Les commandes en gras seront plus particulièrement observées.

Petit dialogue en IMAP

Suit un dialogue tout simple, entre le MUA Thunderbird et un serveur IMAP (Dovecot) configuré pour accepter les échanges en plaintext. Le compte lu n'a pas de dossiers particuliers, à part la « corbeille » (Trash). Il n'y a pas de nouveaux messages dans la boite. On peut difficilement faire plus simple, comme le montre l'illustration.


No.     Time        Source                Destination           Protocol Info
      4 0.000665    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * OK Dovecot ready.
      5 0.010322    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 1 capability
      7 0.010724    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * CAPABILITY IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN NAMESPACE LOGIN-REFERRALS QUOTA STARTTLS AUTH=PLAIN
      8 0.056690    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 2 authenticate plain
      9 0.057215    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: + 
     10 0.057487    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: AHN5c29wQG1haXNvbi5tcnMAd3preHJsZQ==
     12 1.748651    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: 2 OK Logged in.
     13 1.749334    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 3 namespace
     15 1.750784    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * NAMESPACE (("" ".")) NIL NIL
     16 1.752712    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 4 lsub "" "*"
     17 1.753294    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * LSUB () "." "Trash"
     18 1.754174    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 5 list "" "INBOX"
     19 1.754645    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * LIST (\HasNoChildren) "." "INBOX"
     20 1.762273    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 6 select "INBOX"
     21 1.763705    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
     22 1.764358    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 7 getquotaroot "INBOX"
     23 1.765468    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * QUOTAROOT "INBOX" ""
     24 1.765912    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 8 UID fetch 1:* (FLAGS)
     25 1.767333    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * 1 FETCH (FLAGS (\Seen) UID 1)
     26 1.774399    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 9 IDLE
     27 1.775210    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: + idling
     29 8.352640    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: DONE
     30 8.352984    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: 9 OK Idle completed.
     31 8.353243    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 10 close
     32 8.354027    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: 10 OK Close completed.
     33 8.354250    pchris.maison.mrs     janus.maison.mrs      IMAP     Request: 11 logout
     34 8.354431    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: * BYE Logging out
     35 8.354688    janus.maison.mrs      pchris.maison.mrs     IMAP     Response: 11 OK Logout completed.

Pas moins de 11 commandes sont envoyées au serveur. Regardons-les de plus près.

CommandeDescription
capabilitydemande la liste des possibilités que le serveur supporte.
authenticateindique au serveur un mécanisme d'authentification. Si le serveur supporte le mécanisme d'authentification demandé, il exécute un échange protocolaire d'authentification afin d'authentifier et identifier le client. Il est aussi possible d'utiliser la commande login, plus rudimentaire car elle ne supporte que le nom d'utilisateur et son mot de passe en texte clair.
namespacePour aller vite, cette commande retourne ce qu'il faut pour que l'utilisateur puisse connaitre les dossiers auxquels il peut accéder et souscrire, ce qui peut inclure les dossiers partagés, prévus dans le protocole IMAP
lsubpermet d'obtenir à partir d'un point de référence la liste de dossiers auxquels le client a souscrit (qu'il désire voir dans son client).
listpermet d'obtenir à partir d'un point de référence la liste de dossiers existants
selectsélectionne une boite aux lettres, ainsi les messages dans la boite aux lettres sont accessibles. Cette commande renvoie le nombre total de messages (EXISTS), et le nombre de nouveaux messages (RECENT)
getquotarootComme son nom le laisse penser, cette commande renvoie l'état d'occupation de l'espace alloué, lorsque les quotas sont activés sur le serveur IMAP
uids'utilise avec les commandes COPY, FETCH, STORE ou encore SEARCH. Son utilité est de renvoyer un index unique plutôt qu'un numéro de séquence, comme le feraient les commandes COPY, FETCH, STORE et SEARCH
fetchcette commande dispose d'une syntaxe assez complexe. il est possible d'obtenir par elle de nombreuses informations sur un message ou un lot de messages. Dans l'exemple, Thunderbird se contente de récupérer les drapeaux attachés à chaque message présent dans INBOX
idle lorsque le serveur supporte cette commande, il permet au client d'être informé en temps réel de l'arrivée de nouveaux messages
close assez similaire à EXPUNGE, cette commande détruit de façon définitive tous les messages qui ont le drapeau deleted. Elle ne renvoie pas de compte rendu, comme le fait EXPUNGE. Thunderbird n'envoie pas cette commande par défaut. Il faut le lui indiquer dans sa configuration avancée, comme expliqué dans cette astuce
logoutLogout met fin à la session IMAP

Comme nous n'allons pas coder un client IMAP, nous n'irons pas beaucoup plus loin. Il est vivement recommandé, si l'on désire approfondir ce protocole, de s'installer un serveur SMTP et un serveur IMAP et de jouer avec par l'entremise de Telnet. Nous allons d'ailleurs avoir dans la suite un petit aperçu de la complexité de ce jeu.

Points de repère

Encore une fois, rien ne vaut la lecture du RFC 3501 (ce ne sera pas faute d'avoir insisté). Voici tout de même quelques points forts du protocole.

Port par défaut

Un serveur IMAP écoute par défaut sur le port 143. Si l'on n'utilise ni TLS ni IMAPS, l'échange se fait en texte clair (y compris éventuellement le nom d'utilisateur et le mot de passe) et Telnet permet de jouer aux MUAs les plus évolués.

Syntaxe

Premier point, les commandes doivent être indexées, contrairement à POP. Autrement dit, chaque commande doit être précédée d'un index unique. Ceci permet dans certaines conditions d'envoyer au serveur une nouvelle commande alors que l'on n'a pas encore reçu la réponse de la précédente.

Les « flags »

Les commandes peuvent être envoyées en caractères majuscules ou en minuscules. Il vaut mieux le faire en majuscules.

\SeenLe message a été lu
\AnsweredIl a été répondu au message
\FlaggedLe message est marqué pour lui donner une attention perticulière
\DeletedLe message est supprimé pour que plus tard un EXPUNGE ou un CLOSE puisse le supprimer physiquement sur le serveur
\DraftLe message n'a pas été entièrement composé. Il est marqué en tant que brouillon
\Recent Le message est arrivé dans cette boite aux lettres après la dernière consultation de celle-ci. Les sessions ultérieures ne verront pas l'état \Recent pour ce message. Ce drapeau ne peut être modifié par le client. S'il n'est pas possible de déterminer si oui ou non, cette session est la première session a être notifiée du message, alors ce message DEVRA (SHOULD) être considéré comme récent

Quelques commandes utiles

Il existe des commandes qui peuvent être utilisées sans authentification préalable (très peu) et d'autres qui ne peuvent l'être qu'après avoir été authentifié.

CAPABILITY

C'est une commande importante, elle permet au client de savoir ce dont le serveur est capable. Tous les serveurs IMAP n'ont pas les mêmes possibilités. Cette commande peut être envoyée au serveur avant l'authentification. Il est même recommandé de le faire, de manière à choisir le moyen d'authentification le plus approprié. Exemples :

un serveur uw-imapd

10 capability
* CAPABILITY IMAP4REV1 LITERAL+ IDLE UIDPLUS NAMESPACE CHILDREN MAILBOX-REFERRALS BINARY 
UNSELECT ESEARCH WITHIN SCAN SORT THREAD=REFERENCES THREAD=ORDEREDSUBJECT MULTIAPPEND 
SASL-IR LOGIN-REFERRALS STARTTLS LOGINDISABLED
10 OK CAPABILITY completed

un serveur Dovecot

10 capability
* CAPABILITY IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ 
IDLE CHILDREN NAMESPACE LOGIN-REFERRALS QUOTA STARTTLS AUTH=PLAIN
10 OK CAPABILITY completed

un autre serveur Dovecot, configuré différemment

10 capability
* CAPABILITY IMAP4rev1 SASL-IR SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ 
IDLE CHILDREN NAMESPACE LOGIN-REFERRALS STARTTLS AUTH=PLAIN
10 OK CAPABILITY completed

un serveur Courier-imapd

10 capability
* CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES 
SORT QUOTA IDLE ACL ACL2=UNION STARTTLS LOGINDISABLED
10 OK CAPABILITY completed

un serveur Cyrus-imapd

10 capability
* CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID 
NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND BINARY SORT THREAD=ORDEREDSUBJECT 
THREAD=REFERENCES ANNOTATEMORE IDLE STARTTLS LOGINDISABLED
10 OK Completed

Notez STARTTLS et LOGINDISABLED. L'une permet de passer en mode chiffré, l'autre indique que la commande LOGIN qui passe le nom d'utilisateur et le mot de passe en clair n'est pas acceptée par le serveur.

LSUB et LIST

Ces deux commandes permettent de savoir quels sont les répertoires souscrits et existants. Exemple :

* OK Dovecot ready.
10 login chris@maison.mrs epikoi
10 OK Logged in.
20 lsub "*" "*"
* LSUB () "." "Trash"
20 OK Lsub completed.
30 list "*" "*"
* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasNoChildren) "." "INBOX"
30 OK List completed.
40 unsubscribe "Trash"
40 OK Unsubscribe completed.
50 lsub "*" "*"
50 OK Lsub completed.
60 list "*" "*"
* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasNoChildren) "." "INBOX"
60 OK List completed.
70 logout
* BYE Logging out
70 OK Logout completed.
Connection closed by foreign host.

Au début de la session, LSUB dit que chris@maison.mrs est abonné au dossier Trash. La commande LIST indique qu'il y a un autre dossier : INBOX. Mais à celui-ci l'utilisateur est obligatoirement abonné.

La commande UNSUBSCRIBE permet de se désabonner à Trash. En effet la commande LSUB n'indique plus rien, ce qui ne veut pas dire que le dossier n'existe plus, puisque la commande LIST l'affiche toujours.

SELECT

Permet de sélectionner un dossier et d'avoir un compte rendu de son contenu. Pour les besoins, envoyons un message à chris@maison.mrs et manipulons un peu :

20 select INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 6 EXISTS
* 1 RECENT
* OK [UNSEEN 5] First unseen.
* OK [UIDVALIDITY 1216295789] UIDs valid
* OK [UIDNEXT 7] Predicted next UID
20 OK [READ-WRITE] Select completed.

Le fait de sélectionner INBOX nous apprend principalement que dedans il y a :

  • 6 messages ;
  • 1 est RECENT ;
  • le premier message non lu a l'index 5.
UID et FETCH

Pour en savoir plus, il faut utiliser ce couple infernal, avec la bonne syntaxe. Ici, nous voulons juste avoir le détail des FLAGS pour tous les messages présents dans INBOX :

30 uid fetch 1:* (FLAGS)
* 1 FETCH (FLAGS (\Seen) UID 1)
* 2 FETCH (FLAGS (\Seen) UID 2)
* 3 FETCH (FLAGS (\Seen) UID 3)
* 4 FETCH (FLAGS (\Seen) UID 4)
* 5 FETCH (FLAGS () UID 5)
* 6 FETCH (FLAGS (\Recent) UID 6)
30 OK Fetch completed.

Ce qui nous apprend que :

  • les messages 1 à 4 ont été lus ;
  • le message 5 était déjà présent lors de la dernière consultation, mais n'a pas été lu ;
  • le message 6 est Recent. Il n'était pas présent lors de la dernière consultation.

Est-ce à dire que le seul fait d'ouvrir une session IMAP peut changer des flags ? Absolument. La preuve :

40 logout
40 OK Logout completed.
Connection closed by foreign host.
chris@pchris2:~$ telnet janus.maison.mrs 143
Trying 192.168.0.18...
Connected to janus.maison.mrs.
Escape character is '^]'.
* OK Dovecot ready.
10 login chris@maison.mrs epikoi
10 OK Logged in.
20 select "INBOX"
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 6 EXISTS
* 0 RECENT
* OK [UNSEEN 5] First unseen.
* OK [UIDVALIDITY 1216295789] UIDs valid
* OK [UIDNEXT 7] Predicted next UID
20 OK [READ-WRITE] Select completed.
30 uid fetch 1:* (FLAGS)
* 1 FETCH (FLAGS (\Seen) UID 1)
* 2 FETCH (FLAGS (\Seen) UID 2)
* 3 FETCH (FLAGS (\Seen) UID 3)
* 4 FETCH (FLAGS (\Seen) UID 4)
* 5 FETCH (FLAGS () UID 5)
* 6 FETCH (FLAGS () UID 6)
30 OK Fetch completed.

Le seul fait d'avoir fermé la session IMAP puis d'en avoir ouvert une autre fait que le message 6 n'est plus Recent. Soyons clairs. Ceci ne veut pas dire qu'il a été lu. Un message lu a le flag Seen La preuve :

40 uid FETCH 6 BODY[HEADER]
* 6 FETCH (UID 6 FLAGS (\Seen) BODY[HEADER] {811}
Return-Path: <root@janus.nain-t.net>
Delivered-To: chris@maison.mrs
Received: from localhost (localhost [127.0.0.1])
	by janus.nain-t.net (Postfix) with ESMTP id C47C64000B3
	for <chris@maison.mrs>; Sun, 20 Jul 2008 17:58:32 +0200 (CEST)
X-Virus-Scanned: Debian amavisd-new at janus.nain-t.net
Received: from janus.nain-t.net ([127.0.0.1])
	by localhost (janus.nain-t.net [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id UPxwk-p3hN85 for <chris@maison.mrs>;
	Sun, 20 Jul 2008 17:58:17 +0200 (CEST)
Received: by janus.nain-t.net (Postfix, from userid 0)
	id C886740009C; Sun, 20 Jul 2008 17:58:17 +0200 (CEST)
To: chris@maison.mrs
Subject: test IMAP
Message-Id: <20080720155817.C886740009C@janus.nain-t.net>
Date: Sun, 20 Jul 2008 17:58:17 +0200 (CEST)
From: root@janus.nain-t.net (root)

)
40 OK Fetch completed.
40 uid fetch 1:* (FLAGS)
* 1 FETCH (FLAGS (\Seen) UID 1)
* 2 FETCH (FLAGS (\Seen) UID 2)
* 3 FETCH (FLAGS (\Seen) UID 3)
* 4 FETCH (FLAGS (\Seen) UID 4)
* 5 FETCH (FLAGS () UID 5)
* 6 FETCH (FLAGS (\Seen) UID 6)
40 OK Fetch completed.

uid FETCH 6 BODY[HEADER] signifie que l'on souhaite lire le texte du message d'index 6, mais seulement son en-tête. Cette demande fait que par la suite, le message 6 est marqué comme Seen.

STARTTLS

Cette commande permet de négocier entre le client et le serveur une méthode de chiffrement des données échangées. Le serveur doit présenter un certificat (avec sa clé publique) et le client doit accepter ce certificat. Soit automatiquement parce qu'il est signé par une autorité de confiance connue, soit manuellement. STARTTLS employé avant AUTHANTICATE permet de chiffrer aussi la procédure de login. Il n'est que trop conseillé d'utiliser cette méthode si le serveur le permet.

Supprimer un message

Vous avez bien lu jusqu'au bout tous les RFCs impliqués dans le protocole IMAP et vous avez compris qu'il n'y a pas de commande simple prévue pour supprimer un message. La commande DELETE s'applique à des dossiers, pas à des messages. Comment faire alors ? Il y a deux étapes à franchir, et il est absolument fondamental d'en comprendre le principe ! (Notez le…).

Marqué avec \Deleted

Il faut utiliser la commande STORE pour placer sur le message visé le flag \Deleted :

50 store 6 +FLAGS (\Deleted)
* 6 FETCH (FLAGS (\Deleted \Seen))
50 OK Store completed.
60 uid fetch 1:* (FLAGS)
* 1 FETCH (FLAGS (\Seen) UID 1)
* 2 FETCH (FLAGS (\Seen) UID 2)
* 3 FETCH (FLAGS (\Seen) UID 3)
* 4 FETCH (FLAGS (\Seen) UID 4)
* 5 FETCH (FLAGS () UID 5)
* 6 FETCH (FLAGS (\Deleted \Seen) UID 6)
60 OK Fetch completed.

Vous l'avez compris, ceci n'a rien effacé du tout. Nous avons juste ajouté le flag \Deleted au message d'index 6. Dans les MUA graphiques, cette opération peut être diversement visualisée :

  • le message semble avoir disparu, ce qui est une très mauvaise approche, car l'utilisateur non averti peut penser légitimement que le message est détruit.
  • le message apparait barré, mais est toujours visible. C'est probablement la meilleure approche.

Devinez laquelle choisissent la plupart des MUA ? La première bien sûr. Non contents de ça, ils créent automatiquement un répertoire Trash dans lequel ils copient les messages marqués comme effacés. Moralité, l'utilisateur (non averti) croit faire du ménage, en fait, il ajoute des copies de messages en plus dans son espace, en attendant de vider la poubelle.

Ce détail a son importance lorsque l'on a atteint le quota fixé par le fournisseur du service. Refaire un peu de place peut s'avérer impossible si l'on n'a pas compris ce fonctionnement.

EXPUNGE ou CLOSE

EXPUNGE a pour mission de détruire physiquement tous les messages marqués \Deleted dans le dossier courant. CLOSE fait la même chose en refermant le dossier courant. Exemple :

70 close
70 OK Close completed.
80 select "INBOX"
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 5 EXISTS
* 0 RECENT
* OK [UNSEEN 5] First unseen.
* OK [UIDVALIDITY 1216295789] UIDs valid
* OK [UIDNEXT 7] Predicted next UID
80 OK [READ-WRITE] Select completed.
90 uid fetch 1:* (FLAGS)
* 1 FETCH (FLAGS (\Seen) UID 1)
* 2 FETCH (FLAGS (\Seen) UID 2)
* 3 FETCH (FLAGS (\Seen) UID 3)
* 4 FETCH (FLAGS (\Seen) UID 4)
* 5 FETCH (FLAGS () UID 5)
90 OK Fetch completed.

Le message d'index 6, qui était marqué \Deleted à bien disparu de INBOX. EXPUNGE et CLOSE sont de vrais effaceurs.

Malheureusement, les MUA communs n'emploient pas par défaut n'i l'un ni l'autre de ces effaceurs. Thunderbird peut le faire si on le lui demande, mais il faut passer par la configuration avancée et ce n'est pas trivial pour l'utilisateur (non averti).

Jouons un peu

Ami lecteur, pour toi de vérifier que tu as bien assimilé tout ceci le temps maintenant est venu. Pour t'aider dans cette quête, une petite épreuve voici. Une suite de commandes IMAP va suivre. A toi ce qui est fait, de comprendre et d'expliquer .

Etat initial

Notre compte se présente comme ceci dans Thunderbird : Il y a donc 3 messages dans INBOX.

Jeu de commandes

Nous nous connectons avec Telnet sur le serveur et envoyons les commandes suivantes :

10 login chris@maison.mrs epikoi
10 OK Logged in.
20 list "*" "*"
* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasNoChildren) "." "INBOX"
20 OK List completed.
30 create Dossier_1
30 OK Create completed.
40 create Dossier_1.SousDossier_1
40 OK Create completed.
50 create INBOX.Rangement
50 OK Create completed.
60 subscribe INBOX.Rangement
60 OK Subscribe completed.
70 subscribe Dossier_1
70 OK Subscribe completed.
80 subscribe Dossier_1.SousDossier_1
80 OK Subscribe completed.
90 select INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 3 EXISTS
* 0 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1216295789] UIDs valid
* OK [UIDNEXT 10] Predicted next UID
90 OK [READ-WRITE] Select completed.
100 rename Dossier_1 Archive
100 OK Rename completed.
110 list "*" "*"   
* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasChildren) "." "INBOX"
* LIST (\HasChildren) "." "Archive"
* LIST (\HasNoChildren) "." "INBOX.Rangement"
* LIST (\HasNoChildren) "." "Archive.SousDossier_1"
110 OK List completed.
120 rename Archive.SousDossier_1 Archive.2007-2008
120 OK Rename completed.
130 uid fetch 1:* (FLAGS)
* 1 FETCH (FLAGS () UID 7)
* 2 FETCH (FLAGS () UID 8)
* 3 FETCH (FLAGS () UID 9)
130 OK Fetch completed.
140 copy 1:2 Archive.2007-2008
140 OK Copy completed.
150 copy 3 INBOX.Rangement
150 OK Copy completed.
160 store 1:3 +FLAGS (\Deleted)
* 1 FETCH (FLAGS (\Deleted))
* 2 FETCH (FLAGS (\Deleted))
* 3 FETCH (FLAGS (\Deleted))
160 OK Store completed.
170 expunge
* 3 EXPUNGE
* 2 EXPUNGE
* 1 EXPUNGE
170 OK Expunge completed.
180 logout
* BYE Logging out
180 OK Logout completed.
Connection closed by foreign host.

Ami lecteur, peux-tu prévoir ce que le client va désormais trouver dans son Thunderbird, à la prochaine ouverture ?

Etat final

Ami lecteur, avais-tu vu le piège ?

Reprenons avec Telnet :

10 login chris@maison.mrs epikoi
10 OK Logged in.
20 lsub "*" "*"
* LSUB () "." "INBOX.Rangement"
* LSUB () "." "Dossier_1"
* LSUB () "." "Dossier_1.SousDossier_1"
20 OK Lsub completed.

Ce n'est pas parce que l'on a renommé les dossiers, que les abonnements ont été mis à jour. Il faut le faire manuellement :

30 unsubscribe Dossier_1
30 OK Unsubscribe completed.
40 unsubscribe Dossier_1.SousDossier_1
40 OK Unsubscribe completed.
50 list "*" "*"
* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasChildren) "." "INBOX"
* LIST (\HasChildren) "." "Archive"
* LIST (\HasNoChildren) "." "INBOX.Rangement"
* LIST (\HasNoChildren) "." "Archive.2007-2008"
50 OK List completed.
60 subscribe Archive
60 OK Subscribe completed.
70 subscribe Archive.2007-2008
70 OK Subscribe completed.
80 logout
* BYE Logging out
80 OK Logout completed.

Voilà qui devrait aller mieux : Nettement. Les dossiers sont à jour et leur contenu aussi. Puisque nous y sommes et puisque nous avons la main sur le serveur (Dovecot, en l'occurrence)…

janus:/home/virtual/mail/maison.mrs/chris/Maildir# ls -la
total 44
drwx------ 9 vmail vmail  4096 2008-07-20 19:31 .
drwx------ 3 vmail vmail    20 2008-07-17 13:56 ..
drwx------ 5 vmail vmail    56 2008-07-20 19:10 .Archive
drwx------ 5 vmail vmail   148 2008-07-20 19:35 .Archive.2007-2008
drwx------ 2 vmail vmail     6 2008-07-20 19:21 cur
-rw------- 1 vmail vmail   144 2008-07-20 19:21 dovecot.index
-rw------- 1 vmail vmail 20480 2008-07-20 19:21 dovecot.index.cache
-rw------- 1 vmail vmail  2984 2008-07-20 19:23 dovecot.index.log
-rw------- 1 vmail vmail   377 2008-07-20 19:05 dovecot-uidlist
drwx------ 5 vmail vmail   148 2008-07-20 19:36 .INBOX.Rangement
-rw------- 1 vmail vmail   138 2008-07-20 19:21 maildirsize
drwx------ 2 vmail vmail     6 2008-07-20 19:05 new
-rw------- 1 vmail vmail    42 2008-07-20 19:31 subscriptions
drwx------ 2 vmail vmail     6 2008-07-20 19:05 tmp
drwx------ 5 vmail vmail   148 2008-07-20 19:04 .Trash

Notez les analogies, mais INBOX n'y est pas ?

C'est normal. En fait, Dovecot range dans new les message qui ne sont pas encore \Seen et dans cur les messages \Seen. INBOX est donc en réalité un « faux dossier » qui représente le contenu de new et de cur.

Nous sommes dans une architecture de type Maildir la plus courante pour faire de l'IMAP. Dovecot, comme Courier-imap rangent les messages à peu près de la même manière. En revanche, Cyrus-imap utilise une autre stratégie, mais pour le client comme pour le protocole, ceci importe peu.

Conclusion

Tout ceci avait pour but de montrer la supériorité d'IMAP sur son concurrent POP3. Sa plus grande complexité aussi.

IMAPS, tout comme POP3S, utilisent une connexion entièrement chiffrée dès le départ, mais les protocoles demeurent identiques. IMAP, tout comme POP3, peut implémenter la commande STARTTLS, qui met en œuvre un chiffrement, mais après établissement de la connexion. De plus, comme il y a négociation, si le client invoque STARTTLS et que le serveur ne sait pas y répondre, il est possible de continuer sans chiffrement (suivant la configuration du MUA).

IMAPS n'utilise pas le port 143, mais le port 993.