====== 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.