Category Archives: email

W8 Mail App vs Exim and Dovecot

The Windows 8 Mail ‘app’ is fussy about who it will talk to, and gives absolutely no clues about what it thinks is wrong.  It just refers the user to their system administrator.

But, with help from Eric Lee Green’s blog, I finally cracked it.

I have a Debian server running Exim4 (for SMTP) and Dovecot (IMAP).

Firstly I needed up-to-date self-signed SSL certificates for each of these (which I should have had anyway, but email clients such as Thunderbird are much less fussy).

For Exim, that means running

# bash /usr/share/doc/exim4-base/examples/exim-gencert

Debian hides the certificate-generating script for Dovecot in the .deb package, so you have to run

# rm /etc/dovecot/dovecot.pem
# rm /etc/dovecot/private/dovecot.pem
# dpkg-reconfigure dovecot-core

The next operation is to get the public certificate files (not the ones in private directories, obviously), i.e. exim.crt and dovecot.pem onto the Windows 8 machine.  I used psftp to copy them to the desktop.  Rename dovecot.pem to dovecot.crt so that Windows knows what to do with it.  Then, for each one in turn:

  • right-click on it, and choose ‘Install Certificate’
  • choose ‘Current User’ (unless you know better), and click on ‘Next’
  • choose ‘Place all certifcates in the following store’, and browse to select ‘Trusted Root Certification Authorities’.
  • click on ‘Next’, then ‘Finish’.  It will ask if you’re sure — it’s up to you to be sure that you’ve got the right certificate.

Finally the Mail app should now let you set up an account.  Make sure that the server names you use match the ones in the certificate.  To check, run this (back on Debian):

# openssl x509 -in /etc/exim4/exim.crt -text -noout
# openssl x509 -in /etc/dovecot/dovecot.pem -text -noout

and examine the output.

A final note: W8 Mail, being the half-baked toy that it is, doesn’t offer STARTTLS as a connection option, only the ‘obsolete’ (according to Hazel) SSMTP protocol — what the app refers to as simply ‘SSL’.   So you’ll have to set up Exim to do that.

Trying to do SSL on port 587 (i.e. expecting STARTTLS), I get:

2013-12-15 12:42:47 SMTP protocol synchronization error (input sent without waiting for greeting): rejected connection from H=example.org.uk [1.2.3.4] input="\026\003\00
2013-12-15 12:42:47 TLS error on connection from example.org.uk [1.2.3.4] (recv): A TLS packet with unexpected length was received.                                     
2013-12-15 12:42:47 TLS error on connection from example.org.uk [1.2.3.4] (send): The specified session has been invalidated for some reason.

even after applying the alleged fix at https://bugs.launchpad.net/ubuntu/+source/gnutls13/+bug/1007231.

Using nametrans with offlineimap

(Originally posted on the offlineimap mailing list on 15 Jan 2012)

I’ve finally got offlineimap’s ‘nametrans’ feature to do what I want.

Part of the problem was that I found the documentation and examples to be somewhat ambiguous in terms of which direction the translation would happen.

Anyway, I’ve got it working, so here are my notes which will hopefully be helpful to others.

The ‘nametrans’ configuration option allows conversion between different folder names on the local and remote repositories.

nametrans specifies a Python expression which, given each folder name from the repository in turn, returns the equivalent name on the other repository.

In the configuration of the local repository, the nametrans code receives each local folder name, and returns the name of the equivalent remote folder.

In the remote repository configuration, the nametrans code gets the remote folder names, one at a time, and returns the equivalent local names.

Here’s a real example. My remote repository is on my ISP’s server. The ISP’s spam filter puts spam emails into a folder called ‘Spam’, and deleted emails into ‘Trash’. The local repository, on a Debian server running Dovecot IMAP, is accessed by users via Outlook, which likes to use the folder name ‘Junk E-mail’ for spam and ‘Deleted Items’ for deleted emails.

So to avoid confusion, I’ve set up name translations:

[Repository LocalIMAP]
type = IMAP
remotehost = localhost
...
nametrans = lambda foldername: re.sub ('^Junk E-mail$', 'Spam',
re.sub ('^Deleted Items$', 'Trash',
foldername))

[Repository RemoteIMAP]
type = IMAP
remotehost = isp.example.com
...
nametrans = lambda foldername: re.sub ('^Spam$', 'Junk E-mail',
re.sub ('^Trash$', 'Deleted Items',
foldername))

I won’t explain Python lambdas and regular expressions here. But beginners should note

  1. the variable name after the word ‘lambda’ can be anything you like, but must be the same as is used in the expression after the ‘:’; it makes sense to call it ‘foldername’, or just ‘f’ if you don’t like typing.
  2. the re.sub function takes three arguments:
    1. regular expression to match against the third argument
    2. the string to return if there’s a match
    3. the value to match against — here the folder name.
  3. the use of ^ and $ to mark the beginning and end of the match, i.e. to make sure the whole folder name is matched.
  4. if there is no match, re.sub() returns the folder name unchanged.
  5. re.sub() can be nested to allow more than one translation.

With this configuration, offlineimap will synchronise the local ‘Junk E-mail’ folder with the remote ‘Spam’ folder, and local ‘Deleted Items’ with remote ‘Trash’ in both directions.

Problems will occur if the ‘foreign’ name exists as a folder. For example, if ‘Trash’ exists on the local repository, you’ll get this error message:

ERROR: INFINITE FOLDER CREATION DETECTED! Folder 'Trash' (repository
'LocalIMAP') would be created as folder 'Trash' (repository
'RemoteIMAP'). The latter becomes 'Deleted Items' in return, leading to
infinite folder creation cycles.
SOLUTION: 1) Do set your nametrans rules on both repositories so they
lead to identical names if applied back and forth. 2) Use folderfilter
settings on a repository to prevent some folders from being created on
the other side.

I found that message only partially helpful: does it mean use both solutions 1) and 2), or either?

Solution 3) would be “Remove folder ‘Trash’ from the local repository”, but if you don’t want to do that, then solution 2) is required: add a folderfilter to stop the local ‘Trash’ from being copied to the remote side, like this (in the local repository configuration):

folderfilter = lambda foldername: foldername not in ['Trash']

That folderfilter is only required, in this example, if ‘Trash’ already exists locally, or if there is any danger of it being created in the future. It’s always possible that a translated folder name could be created by the user, so it’s safest to add folderfilters for any translated folder names. To complete my real-world example from above, I need:

[Repository LocalIMAP]
# Has folders: Inbox, Junk E-mail, Deleted Items, etc.
type = IMAP
remotehost = localhost
...
nametrans = lambda foldername: re.sub ('^Junk E-mail$', 'Spam',
                                re.sub ('^Deleted Items$', 'Trash',
                                foldername))
folderfilter = lambda foldername: foldername not in ['Spam', 'Trash']

[Repository RemoteIMAP]
# Has folders: Inbox, Spam, Trash, etc.
type = IMAP
remotehost = isp.example.com
...
nametrans = lambda foldername: re.sub ('^Spam$', 'Junk E-mail',
                                re.sub ('^Trash$', 'Deleted Items',
                                foldername))
folderfilter = lambda foldername: foldername not in ['Junk E-mail',
                                                     'Deleted Items']

I hope that’s clear, and that it’s helpful to people. Perhaps some of it could be included in the offlineimap documentation.