====== IMAP protocol ====== Example of an IMAP session: $ telnet mail.texnet.it 143 Trying 217.19.150.6... Connected to mail.texnet.it. Escape character is '^]'. * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc. See COPYING for distribution information. a1 CAPABILITY * CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS a1 OK CAPABILITY completed a2 LOGIN niccolo ******** a2 OK LOGIN Ok. a3 LIST "" "*" * LIST (\Marked \HasNoChildren) "." "INBOX" a3 OK LIST completed a4 SELECT INBOX * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent) * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited * 2856 EXISTS * 2856 RECENT * OK [UIDVALIDITY 1163517848] Ok * OK [MYRIGHTS "acdilrsw"] ACL a4 OK [READ-WRITE] Ok a5 FETCH 5 FAST * 5 FETCH (FLAGS (\Recent) INTERNALDATE "25-Nov-2005 22:09:41 +0100" RFC822.SIZE 2763) a5 OK FETCH completed. a6 FETCH 3 (flags body[header.fields (subject)]) * 3 FETCH (FLAGS (\Recent) BODY[HEADER.FIELDS ("subject")] {94} Subject: Cron [ -x /usr/bin/freshclam ] && /usr/bin/freshclam >/dev/null ) * 3 FETCH (FLAGS (\Seen \Recent)) a6 OK FETCH completed. a7 LOGOUT Some IMAP servers present all the folders as subfolders of the INBOX: a3 LIST "" "*" * LIST (\HasNoChildren) "." "INBOX.Sent" * LIST (\HasNoChildren) "." "INBOX.Trash" * LIST (\HasNoChildren) "." "INBOX.Spam" * LIST (\Marked \HasChildren) "." "INBOX" a4 CREATE INBOX.Archive For other IMAP servers, the folders are outside the INBOX: a3 LIST "" "*" * LIST (\HasNoChildren) "." Spam * LIST (\HasNoChildren \Drafts) "." Drafts * LIST (\HasNoChildren \UnMarked \Sent) "." Sent * LIST (\HasNoChildren \Trash) "." Trash * LIST (\HasNoChildren) "." INBOX a4 CREATE Archive ===== Migrating IMAP folder ===== ==== offlineimap ==== Sincronizza una cartella su server **IMAP remoto** con una **Maildir locale** oppure un altro **server IMAP**. Sembra il programma più flessibile e semplice da utilizzare rispetto a **isync**, **mailsync**, **interimap**, **imapsync** e **imapcopy**.. **ATTENZIONE** :!: Le versioni **6.3.4** di Debian Wheezy e **6.5.4** hanno diversi bug. **ATTENZIONE** :!: La versione **7.3.0** (git20210225) di Debian 11.3 Bullseye ha un bug con le cartelle IMAP che **contengono degli spazi** (vedere pull risolutivo [[https://github.com/OfflineIMAP/offlineimap3/pull/80|#80]]). Un rimedio temporaneo è creare manualmente la cartella IMAP sul server ricevente. Esiste il pacchetto **offlineimap3_0.0~git20211018.e64c254+dfsg-1~bpo11+1_all.deb** in bullseye-backports. **ATTENZIONE** :!: Il programma effettua una sincronizzazione **bidirezionale**, ma noi siamo interessati alla migrazione di una mailbox da un server ad un altro, pertanto **la bidirezionalità è un rischio**. In caso di confusione sul nome delle cartelle tra i due repository e sullo stato dell'ultima sincronizzazione, c'è il **rischio concreto di eliminare i messaggi dal server di origine**. **ATTENZIONE** :!: La versione **8.0.0** (Debian GNU/Linux 12 Bookworm) non riesce a gestire correttamente la sincronizzazione con server Courier IMAP in presenza di sottocartelle di primo livello o ulteriori. Vedere l'**[[https://github.com/OfflineIMAP/offlineimap3/issues/188|issue #188]]**. Pertanto, prima di iniziare la sincronizzazione, è opportuno indagare quali cartelle sono presenti sul server di origine e **il loro percorso**. Inoltre, se si cambia il file di configurazione, è opportuno rimuovere tutti i file di stato che vengono salvati in **$HOME/.offlineimap/** relativi ad **%%Account-*%%** e **%%Repository-*%%**. === Esempio #1: da IMAP a Maildir === Il primo esempio riguarda una migrazione da repository **IMAP remoto** a **Maildir locale**. Prepariamo il file di configurazione **offlineimap-imap-maildir.conf**: [general] accounts = Test [Account Test] remoterepository = RemoteIMAP localrepository = Localhost [Repository RemoteIMAP] type = IMAP # Strip the "INBOX" prefix when copying to a local Maildir, examples: # 'INBOX' => '.' # 'INBOX.Trash' => '.Trash' # 'INBOX.Sent' => '.Sent' nametrans = lambda foldername: re.sub('^INBOX\.*', '.', foldername) remotehost = mail.example.org remoteuser = username remotepass = MySecret createfolders = False sslcacertfile = /usr/share/ca-certificates/mozilla/Actalis_Authentication_Root_CA.crt ssl_version = tls1_2 # If you don't want IMAPS on port 993, you can use STARTTLS on port 143. #ssl = no #starttls = yes [Repository Localhost] type = Maildir localfolders = /home/username2/Maildir Per impostazione predefinita offlineimap tenta una connessione **SSL** su porta **993/TCP**, verificando il certificato del server remoto. Senza l'opzione **sslcacertfile** il client offlineimap non è in grado di inziare la sessione TLS e si blocca con il seguente errore: offlineimap.error.OfflineImapError: No CA certificates and no server fingerprints configured. You must configure at least something, otherwise having SSL helps nothing. Per vedere quale Certification Authority deve essere usata è necessario recuperare il certificato SSL dal server remoto, ad esempio con il comando: openssl s_client -showcerts -connect mail.example.org:993 Quindi si ispeziona la **certificate chain** alla ricerca di **O**rganization e **C**ommon **N**ame con valori del tipo: * O = Actalis S.p.A., CN = Actalis Organization Validated Server CA G3 * O = Let's Encrypt, CN = R3 Avendo installato il pacchetto **ca-certificates**, si cerca nella directory **/usr/share/ca-certificates/mozilla/** il certificato giusto da usare. Dopo aver abilitato SSL si può incappare anche nel seguente errore: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:727) Questo significa che il server utilizza una versione debole di SSL, vulnerabile ad attacchi del tipo //Factoring RSA Export Keys// poiché usa una chiave Diffie-Hellman più corta di 768 byte. In questo caso, se non possiamo correggere il server, è necessario aggiungere l'opzione di configurazione ''ssl_version = tls1_2''. Se si desidera utilizzare una connessione con STARTTLS su porta 143, è necessario aggiungere le opzioni ''ssl = no'' e ''starttls = yes''. Si esegue il programma in modalità **%%--info%%**, senza alcun trasferimento di messaggi: offlineimap --dry-run --info -c ./offlineimap-imap-maildir.conf Nell'output si legge: ... Remote repository 'RemoteIMAP': type 'IMAP' ... Folderlist: INBOX -> INBOX.Drafts -> .Drafts INBOX.Archives.2019 -> .Archives.2019 INBOX.Sent -> .Sent INBOX.Spam -> .Spam INBOX.Trash -> .Trash Local repository 'Localhost': type 'Maildir' Folderlist: Come si vede il server di origine, oltre alla cartella **INBOX**, presenenta alcune sottocartelle che hanno il prefisso **INBOX.**; la regola **re.sub()** nel file di configurazione serve a tradurre il nome delle cartelle dalla nomenclatura IMAP remota alla Maildir locale (ovviamente si deve verificare lo standard adottato dal server IMAP che gira sull'host di destinazione). In particolare: * La INBOX deve essere la cartella radice della Maildir. * Il prefisso INBOX delle sottocartelle deve essere rimosso. * Ogni sottocartella deve avere il punto come prefisso del nome (directory nascosta Unix). Vengono create le cartelle **$HOME/.offlineimap/Repository-RemoteIMAP/** e **$HOME/.offlineimap/Repository-Localhost/**, per il momento vuote, ma che conterranno poi lo stato della sincronizzazione. === Esempio #2: da IMAP a IMAP === In questo esempio di effettua la sincronizzazione fra due server IMAP, quindi senza fare accesso diretto al filesystem. Questo il file di configurazione **offlineimap-imap-imap.conf**: [general] accounts = Test [Account Test] remoterepository = RemoteIMAP localrepository = LocalIMAP [Repository RemoteIMAP] type = IMAP # Strip the "INBOX" prefix when copying to a destination IMAP. # 'INBOX' => 'INBOX' # 'INBOX.Trash' => 'Trash' # 'INBOX.Sent' => 'Sent' nametrans = lambda foldername: re.sub(r'^INBOX\.', '', foldername) remotehost = mail1.example.org remoteuser = username1 remotepass = MySecret1 createfolders = False sslcacertfile = /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt [Repository LocalIMAP] type = IMAP remotehost = mail2.example.org remoteuser = username2 remotepass = MySecret2 sslcacertfile = /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt Si esegue il programma in modalità **%%--info%%**: offlineimap --dry-run --info -c ./offlineimap-imap-imap.conf Verifichiamo l'output: Remote repository 'RemoteIMAP': type 'IMAP' ... Folderlist: INBOX.Drafts -> Drafts INBOX INBOX.Sent -> Sent INBOX.Spam -> Spam INBOX.Trash -> Trash Local repository 'LocalIMAP': type 'MappedIMAP' ... Folderlist: Drafts INBOX Sent Spam Trash Si capisce che i due server IMAP utilizzano una struttura diversa: il primo ha il prefisso ''INBOX.'' per ogni sottocartella, mentre il secondo no. Anche in questo caso è stato necessario utilizzare l'opzione **nametrans** con una opportuna **re.sub()** leggermente diversa dall'esempio #1. Si verifica comunque che il nome ''INBOX'' non viene trasformato, mentre per le sottocartelle avviene la corretta trasformazione che consiste semplicememte nel rimuovere il prefisso ''INBOX.'', compreso il punto. === Sincronizzazione === La sincronizzazione avviene semplicemente eseguendo il comando con l'opportuno file di configurazione. In questo esempio si esegue un thread singolo (opzione **%%-1%%**) e si scrive nel file di log (opzione **%%-l%%**) il debug del protocollo imap e maildir (opzione **%%-d%%**): offlineimap -1 -c offlineimap-imap-imap.conf -d imap,maildir -l offlineimap.log * Lo stato della sincronizzazione viene scritto in **''$HOME/.offlineimap/''** * La ''Maildir'' locale può essere anche vuota, viene riempita opportunamente. * Potrebbe essere necessario specificare l'opzione **''nametrans''** per entrambi i repository, in modo che la sincronizzazione bidirezionale crei le giuste cartelle sul server remoto, ma noi abbiamo preferito utilizzare l'opzione ''createfolders = False'' in modo che non vi sia propagazione di cartelle verso il server origine. === Soluzione problemi === Vedere **[[offlineimap3]]**. ==== isync ==== Consente la sincronizzazione di una **Maildir locale** con un server **IMAP remoto**. * Errore **''malformed UIDVALIDITY status''**, compilata **versione 1.0.6** al posto della versione 1.0.4 fornita da Debian Jessie. * FIXME Esiste un modo di fare trasferimento ricorsivo di tutte le cartelle? Provare l'opzione **''-1''** * FIXME Problemi con le cartelle che contengono spazi nel nome, vedere la soluzione di eseguire direttamente ''mbsync''. * Lo stato della sincronizzazione viene scritto in ogni Maildir nel file **''.mbsyncstate''**. === Uso diretto di mbsync === Per il problema delle cartelle che contengono spazi nel nome, si lancia **''%%isync --write%%''**. Viene generato un file **''mbsync.conf''** che deve essere corretto a mano aggiungendo le doppie virgolette. Quindi si esegue: mbsync --config mbsync.conf ==== mailsync ==== Consente la sincronizzazione di un server **IMAP remoto** con il **filesystem locale** (non Maildir) oppure **altro server IMAP**. **Non supporta il formato Maildir** su filesystem locale. Il programma in effetti si appoggia sulla libreria **c-client** per accedere agli archivi di posta, in passato Debian includeva una patch per supportare Maildir, ma questa patch è stata rimossa (verificato in **libc-client2007e** di Debian Jessie). Con questo file di configurazione **mailsync.conf** si sincronizza un server IMAP (remoto) con uno che gira in localhost: store first-server { server {mail.server1.it/user=user1/novalidate-cert} ref {mail.server1.it} pat * prefix INBOX passwd FirstSecret } store second-server { server {localhost/user=user2/novalidate-cert} ref {localhost} pat * prefix INBOX passwd SecondSecret } channel first-to-second first-server second-server { msinfo .msinfo } Per lanciare la sincronizzazione per la prima volta si cancella un eventuale file di stato **''.msinfo''**: rm .msinfo mailsync -v -d -di -dc -f mailsync.conf first-to-second ==== interimap ==== Effettua la sincronizzazione fra due server IMAP, ma richiede la capability **QRESYNC** su entrambi. ==== imapsync ==== :!: Non presente in Debian 10 Buster. Obsoleto? To migrate an IMAP account from one host1 to host2, there is the **''[[http://www.linux-france.org/prj/imapsync/|imapsync]]''** tool. In this usage example mail messages not longer existing on host1 will be deleted also on host2: #!/bin/sh login1=username_on_host1 passwd1=SecretOnHost1 login2=username_on_host2 passwd2=SecretOnHost2 ./imapsync \ --host1 83.145.162.149 \ --authmech1 LOGIN \ --user1 "$login1" \ --password1 "$passwd1" \ --subscribed \ --host2 127.0.0.1 \ --authmech2 LOGIN \ --user2 "$login2" \ --password2 "$passwd2" \ --subscribe \ --delete2 --expunge2 FIXME Problema con allegati con BODY vuoti: invece di saltare il messaggio il programma si blocca. ==== imapcopy ==== :!: Non presente in Debian 10 Buster. Obsoleto? Il tool non supporta SSL né TLS, inoltre **non effettua una sincronizzazione**, ma una copia; quindi se viene eseguito due volte i messaggi vengono duplicati. Si prepara un file di configurazione **''$HOME/ImapCopy.cfg''** con le seguenti opzioni: SourceServer host1 SourcePort 143 DestServer host2 DestPort 143 converttimezone "UTC" "+0000" converttimezone "UT" "+0000" Copy "login1" "password1" "login2" "password2" Lanciare il comando con l'opzione **''-l''** in modo che venga creato il file di log ''imapcopy.log''. ===== Quota ===== Il protocollo IMAP supporta un meccanismo di "quota volontaria", cioè i vari software (SMTP, IMAP, POP) devono collaborare a mantenere aggiornato un file con le statistiche di occupazione. Per vedere se il server IMAP supporta correttamente la quota: telnet 127.0.0.1 143 * OK [CAPABILITY IMAP4rev1 UIDPLUS ... QUOTA ...] Courier-IMAP ready. a1 LOGIN niccolo MySecret a1 OK LOGIN Ok. a2 GETQUOTAROOT INBOX * QUOTAROOT "INBOX" "ROOT" * QUOTA "ROOT" (STORAGE 6417 19532) a2 OK GETQUOTAROOT Ok. a3 LOGOUT In questo caso il Courier-IMAP implementa una soft-quota, cioè non quella del kernel Linux. Questa softquota è mantenuta nel file **''~/Maildir/maildirsize''** e bisogna che tutti i programmi che scrivono/leggono nella Maildir lo tengano aggiornato. Ad esempio **''procmail'' non lo fa**. Per aggiornare una-tantum il contenuto del file (modificando lo spazio disponibile): maildirmake -q 20000000S Maildir I programmi **''courier-imap''** e **''courier-pop''** si comportano correttamente se trovano il file **''~/Maildir/maildirsize''**, cioè aggiornano il totale dello spazio occupato quando viene eliminato un messaggio. L'aggiornamento di ''maildirsize'' all'arrivo di nuovi messaggi non viene fatto direttamente da Postfix o Exim, si deve utilizzare un opportuno filtro di consegna, come **''maildrop''**. Se qualcuno interviene direttamente sui file nella Maildir, è necessario rigenerare il file ''maildirsize'' come visto sopra. ===== FAM/Gamin library ===== Il server Courier IMAP sfrutta il supporto FAM (File Alteration Monitor) o Gamin. Conviene installare il pacchetto Debian **gamin**. Se non è installata una di queste librerie produce i seguente messaggio di errore: * OK [ALERT] Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library) ====== Courier IMAP ====== La connessione cifrata STARTTLS si appoggia su [[authdaemon_problem]]. Per effettuare debug lato client si può usare Firefox attivando la **Console degli errori** dal menu **Strumenti**. Durante l'aggiornamento da Weezy a Jessie ad esempio si deve risolvere il problema del file ''/etc/courier/dhparams.pem'' che deve passare da 1024 ad almeno 2048 bit.