URL: https://linuxfr.org/users/epeios/journaux/epeios-meta-mail-user-agent-le-protocole-imap Title: Epeios Meta Mail User Agent : le protocole IMAP. Authors: Claude SIMON Date: 2017年01月30日T20:51:51+01:00 License: CC By-SA Tags: gui, cli, html, epeios, mmuaq, imap et pop3 Score: 11 Suite des aventures concernant le développement d'un *MUA*, dont le début vous est rapporté [ici](/users/epeios/journaux/epeios-meta-mail-user-agent-premiere-publication). Après *POP3* (*RFC* 1939) et *Mail Internet Format* (*RFC* 5322), voici le tour d'*IMAP* (*RFC* 3501 et 5530) d'être implémenté (partiellement pour le moment), et notamment la structure générale des messages qui sont échangés entre client et serveur *IMAP*, ce qui facilitera la future implémentation des commandes manquantes. La prise en compte d'*IMAP* n'ayant qu'un impact réduit sur l'application en elle-même (ajout de la possibilité de définir un agent *IMAP*, en plus de *POP3*), telle qu'elle était présentée dans le journal ci-dessus, je vais en profiter pour m'attarder sur l'utilitaire `mmuaq[.exe]`, que vous trouverez dans `processing/mmuaq/` (le lien menant au téléchargement de l’application est donné tout en bas). Cet utilitaire me sert à mettre au point le code avant qu'il ne soit mis en œuvre dans l'application proprement dite, ainsi qu'à dépister les éventuels bugs, compte tenu qu'un utilitaire en ligne de commande est plus facile à débuguer qu'un *daemon*. Notez qu'il ne s'agit **pas** du client en ligne de commande du *MUA* ; ce rôle est dévolu à l'utilitaire `mmuaqcli[.exe]`, qui se trouve dans `frontend/CLI/`. Les commandes disponibles dans *mmuaq* correspondent aux tâches de base nécessaires à le gestion d'un *MUA*. Concernant *IMAP*, il y a deux types de commandes, d'une part les commandes bas-niveau, chacune de ces commandes correspondant à une commande du protocole *IMAP* (avec lancement de quelques commandes accessoires, comme celle consistant à se *logger*, sans quoi peu de commandes *IMAP* pourront s'exécuter sans erreur), et des commandes de plus haut niveau, qui seront les commandes appelées par le *backend* de l'application, et qui nécessitent l'appel à plusieurs commandes *IMAP* de base. Vu ce pourquoi cet utilitaire a été conçu, il a une option `--verbose` qui affiche le contenu de ce qui transite entre le client et le serveur. Ça permet de voir où cela coince lorsqu'il y a un problème. Les informations affichées avec `--verbose`, ainsi que celles affichées sans `--verbose` pour les commandes bas-niveau, subissent un (léger) formatage pour faciliter leur lecture. Ainsi, voici ce qu'un `SELECT` (avec un `LOGIN` et un `LOGOUT`) peut donner lorsqu'on se connecte avec *telnet* sur un serveur *IMAP* (`->` signale les commandes qui ont été saisies dans la console) : $ telnet imap Trying ... Connected to . Escape character is '^]'. * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN] Dovecot ready. -> 0 LOGIN 0 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in -> 1 SELECT inbox * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted. * 661 EXISTS * 0 RECENT * OK [UNSEEN 14] First unseen. * OK [UIDVALIDITY 1409248764] UIDs valid * OK [UIDNEXT 15448] Predicted next UID 1 OK [READ-WRITE] Select completed (0.000 secs). -> 2 LOGOUT * BYE Logging out 2 OK Logout completed. Connection closed by foreign host. Et la même chose avec `mmuaq` (`->` signale les commandes envoyées par le logiciel) : $ mmuaq --imap-select inbox --verbose Capability: IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN OK: Dovecot ready. -> 0 LOGIN Capability: IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE OK: Logged in -> 1 SELECT inbox Flags: (\Answered \Flagged \Deleted \Seen \Draft) PermanentFlags: (\Answered \Flagged \Deleted \Seen \Draft *) OK: Flags permitted. Exists: 661 Recent: 0 Unseen: 14 OK: First unseen. UIDValidity: 1409248764 OK: UIDs valid UIDNext: 15448 OK: Predicted next UID Read-Write OK: Select completed (0.000 secs). -> 2 LOGOUT Bye: Logging out OK: Logout completed. Et la même commande sans `--verbose`, ce qui permet d'obtenir juste les informations retournées par la commande demandée : $ mmuaq --imap-select inbox Flags: (\Answered \Flagged \Deleted \Seen \Draft) PermanentFlags: (\Answered \Flagged \Deleted \Seen \Draft \*) Exists: 661 Recent: 0 Unseen: 14 UIDValidity: 1409248764 UIDNext: 15448 Read-Write Un exemple avec une commande de plus haut niveau (``->`` signale les commandes envoyées par le logiciel, les réponses étant encadrés par ``<-`` et ``--``) : ``` $ mmuaq --imap-RFC822-text inbox 1 --verbose <- * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready. -- -> 0 LOGIN <- 0 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CON LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in -- -> 1 LIST "" "" <- * LIST (\Noselect) "/" "" 1 OK List completed. -- -> 2 SELECT inbox <- * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted. * 3 EXISTS * 0 RECENT * OK [UNSEEN 3] First unseen. * OK [UIDVALIDITY 1483863075] UIDs valid * OK [UIDNEXT 4] Predicted next UID 2 OK [READ-WRITE] Select completed (0.000 secs). -- -> 3 FETCH 1 RFC822.TEXT <- * 1 FETCH (RFC822.TEXT {15} Body mail 1.1 ) 3 OK Fetch completed. -- Body mail 1.1 -> 4 LOGOUT <- * BYE Logging out 4 OK Logout completed. -- ``` Pour pouvoir utiliser les commandes relatives à *IMAP*, il faut créer une section ``IMAP`` dans la section ``Parameters`` du fichier de configuration de l'utilitaire (``mmuaq.xcfg``) avec le contenu suivant : ``` USERNAME PASSWORD ``` avec, pour `HOST_PORT`, l'adresse et le port du serveur *IMAP*, sous la forme *addresse:port*, et pour `USERNAME`et `PASSWORD`, respectivement le *login* et le mot de passe d'un compte *IMAP* du serveur indiqué. À noter que les connexions sécurisées ne sont pas encore prises en charge, mais certains serveurs *IMAP* acceptent des connexions non sécurisées de *localhost*, et permettent facilement de définir une liste d'*IPs* desquelles ils acceptent des connexions non sécurisée. Si vous souhaitez pouvoir vous connecter à plusieurs comptes *IMAP* différents, sans avoir à modifier à chaque fois le fichier de configuration, vous pouvez définir, dans le fichier de configuration, un *Setup* pour chaque compte *IMAP*, et l'activer en passant son identifiant à l'option ``-s|--setup``, comme indiqué dans la page d'aide de l'utilitaire (``mmuaq[.exe] --help``). Pour en savoir plus à propos des *setups*, vous pouvez consulter cette [page](http://q37.info/s/c/setups/). Cet utilitaire permet aussi de lancer des commandes (celles préfixées par `--pop3-`) sur un serveur *POP3*, sous réserve de créer une section ``POP3`` dans la section ``Parameters`` du fichier de configuration, avec le contenu suivant : ``` USERNAME PASSWORD ``` `HOST_PORT`, `USERNAME`et `PASSWORD` ont la même signification que pour la section `IMAP`, et vous pouvez naturellement également utiliser les *[setups](http://q37.info/s/c/setups/)* pour cette section. Voici la liste des commandes acceptées par *mmuaq* : ``` $ mmuaq --help --#Language=fr Utilitaire d'aide au développement de l'application 'MMUAq'. mmuaq --help Affiche cette page. mmuaq --version Affiche la version du programme. mmuaq --license Affiche la licence du programme. mmuaq --b64-encode [ []] Encodage 'Base64'. mmuaq --b64-decode [ []] Decodage 'Base64'. mmuaq --next-tag [<étiquette>] Retourne l'étiquette 'IMAP' suivante. mmuaq --pop3-list [-s|--setup=] [--verbose] [] Affiche des informations sur les courriers d'un serveur 'POP3'. mmuaq --pop3-retrieve [-s|--setup=] [--verbose] Récupère un courrier d'un serveur 'POP3'. mmuaq --pop3-top [-s|--setup=] [--verbose] Affiche le début d'un courrier d'un serveur 'POP3'. mmuaq --pop3-uidl [-s|--setup=] [--verbose] [] Affiche l'identifiant unique des courriers d'un serveur 'POP3'. mmuaq --imap-capability [-s|--setup=] [--verbose] Lance la commande 'CAPABILITY' du protocole 'IMAP'. mmuaq --imap-list [-s|--setup=] [--verbose] Lance la commande 'LIST' du protocole 'IMAP'. mmuaq --imap-lsub [-s|--setup=] [--verbose] Lance la commande 'LSUB' du protocole 'IMAP'. mmuaq --imap-select [-s|--setup=] [--verbose] Lance la commande 'SELECT' du protocole 'IMAP'. mmuaq --imap-fetch [-s|--setup=] [--verbose] [--uid] Lance la commande 'FETCH' du protocole 'IMAP'. mmuaq --imap-folders [-s|--setup=] [--verbose] [] Affiche les sous-dossiers d'un dossier 'IMAP'. mmuaq --imap-RFC822 [-s|--setup=] [--verbose] [--uid] Affiche le 'RFC822' d'un courrier d'un dossier 'IMAP'. mmuaq --imap-RFC822-size [-s|--setup=] [--verbose] [--uid] Affiche le 'RFC822.SIZE' d'un courrier d'un dossier 'IMAP'. mmuaq --imap-RFC822-header [-s|--setup=] [--verbose] [--uid] Affiche le 'RFC822.HEADER' d'un courrier d'un dossier 'IMAP'. mmuaq --imap-RFC822-text [-s|--setup=] [--verbose] [--uid] Affiche le 'RFC822.TEXT' d'un courrier d'un dossier 'IMAP'. mmuaq --imap-uid [-s|--setup=] [--verbose] Affiche l'UID' d'un courrier d'un dossier 'IMAP'. mmuaq --imap-mail-amount [-s|--setup=] [--verbose] Affiche le nombre de courriers d'un dossier 'IMAP'. mmuaq --show-header [ []] Affiche l'entête d'un courrier. mmuaq --get-field [ []] Affiche le contenu du champ d'un courrier. --verbose ('Parameters/Verbose'='true'): Affiche les données échangées avec le serveur. --uid ('Parameters/IMAP/UID'='true'): Lance le version 'UID' de la commande ('UID commande ...'). ('Parameters/@Setup'): Identifiant du 'setup' à utiliser. ('Parameters/Input'): Nom du fichier d'entrée (utilisation de l'entrée standard si absent). ('Parameters/Output'): Nom du fichier de sortie (utilisation de la sortie standard si absent). ('Parameters/MailID'): Identifiant de courrier (nombre, séquence, 'UID'... selon le contexte). ('Parameters/Lines'): Nombre de lignes. ('Parameters/FieldName'): Nom du champ. <étiquette> ('Parameters/Tag'): Étiquette 'IMAP'. ('Parameters/IMAP/Reference'): 'reference name' tel que défini pour le protocole 'IMAP'. ('Parameters/IMAP/Mailbox'): 'mailbox name' tel que défini pour le protocole 'IMAP'. ('Parameters/IMAP/SequenceSet'): 'sequence set' tel que défini pour le protocole 'IMAP'. ('Parameters/IMAP/Items'): 'message data item names or macro' tel que défini pour le protocole 'IMAP'. ('Parameters/IMAP/Folder'): Dossier 'IMAP' ; dossier racine si absent. ``` Comme l'utilitaire est publié sous licence *AGPL*, les sources sont bien entendu consultables. Pour ceux que cela intéresse, voici en particulier ceux qui prennent en charge les différents protocoles : - RFC 3522 (*Internet Message Format*) : [muaimf.h](http://q37.info/s/s/m/muaimf.h) [muaimf.cpp](http://q37.info/s/s/m/muaimf.cpp), - RFC 3501 et 5530 (*IMAP*) [muaimabs.h](http://q37.info/s/s/m/muaimabs.h) [muaimabs.cpp](http://q37.info/s/s/m/muaimabs.cpp): [muaima.h](http://q37.info/s/s/m/muaima.h) [muaima.cpp](http://q37.info/s/s/m/muaima.cpp), - RFC 1939 (*POP3*) : [muapo3.h](http://q37.info/s/s/m/muapo3.h) [muapo3.cpp](http://q37.info/s/s/m/muapo3.cpp), et les sources de l'utilitaire proprement dit, qui met en œuvre ces différents sources : [mmuaq](http://q37.info/s/s/m/mmuaq). Pour la documentation, les sources, les binaires... de l'application en général (qui inclut l'utilitaire détaillé dans ce journal), c'est par [ici](http://q37.info/s/a/mmuaq).

AltStyle によって変換されたページ (->オリジナル) /