DavMail Office365 Bridge
Recently I started at an institution which uses a groupware which is deliberately incompatible with open groupware protocols such as IMAP,SMTP,CalDAV. This leaves the option to use the provided webinterface which I think is inconvenient.
Fortunately there exists the DavMail project, which is a bridge between the ExchangeWebServices and open protocols. It works by being a client to EWS and then exposing a server interface on the usual ports shifted up by 1000 (e.g. IMAP being at 1143 instead of 143). There are two possible operation modes, one as a local deamon to run on desktop systems and one server/headless version. For a single desktop client, the first is fine, but I wanted to have access from my phone too. Unfortunately the headless version does not yet have an oauth workflow to log in with the two-factor authentication. The workaround is to register through the desktop version and then copy the authentication token to the headless deployment.
Acquiring the Authentication Token
Info
skip this section if you don't have 2FA
Install DavMail on a desktop system and keep the default values, except change the authentication method to O365Interactive
.
The easiest way to trigger the MFA authentication is to open the CalDAV interface at http://localhost:1080/ and log in with your email and password.
This opens a dialog of DavMail with a link which you can use in any browser, authenticate to Microsoft and provide the SMS/auth token and authorize the DavMail application. Copy the final link (with the token in the parameters) showing an empty page, back to the DavMail dialog.
After successful authentication, close davmail and locate the davmail.properties
file to extract the line which starts with
davmail.oauth.<user@email.tld>.refreshToken={AES}...
This is your oauth token which keeps you logged in. It is encrypted with your password such that on successful authentication to the DavMail server it can decrypt the token and use it to log into the EWS service.
Preparing a TLS Certificat
When running DavMail as a server, the connection no longer stays on the localhost and must be secured by TLS. Acquire a TLS certificate for the domain you want to run the service on with e.g. Let's Encrypt or ZeroSSL.
This usually returns a key.pem
(unencrypted RSA key) and cert.pem
(with Certificate-Chain). To prepare it for DavMail, it has to be stored in PKCS12 format. First encrypt the private key with a password of your choice:
openssl rsa -aes256 -in key.pem -out key.encrypted
and then create the PKCS12 container with a fresh container password:
openssl pkcs12 -export -in cert.pem -inkey key.encrypted -certfile cert.pem -out davmail.p12 -legacy
Info
depending on your java and openssl versions, you might need the -legacy
option to create the p12
As ACME certificates usually have a 90 day validity, you need to automate this process in a cron script.
Deploying a DavMail server
The easiest option to run the DavMail headless version is as docker image with docker-compose
and the following configuration:
version: "3"
services:
davmail:
image: quay.io/connectical/davmail
ports:
- "1080:1080" # caldav
- "1025:1025" # smtp
- "1143:1143" # imap
volumes:
- logs:/var/log/davmail
- ./davmail.properties:/etc/davmail/davmail.properties
- ./davmail.p12:/etc/davmail/davmail.p12
volumes:
logs
Info
the docker hub image of davmail is no longer maintained and is now pushed to quay.io
The ./davmail.p12
path should point to the previously prepared PKCS12 container.
To prepare the davmail.properties
file, download a default version from https://github.com/ogarcia/docker-davmail/blob/master/.circleci/docker/davmail.properties
and set up the certificate with the matching passwords:
davmail.ssl.keystoreType=PKCS12
davmail.ssl.keystoreFile=/etc/davmail/davmail.p12
davmail.ssl.keystorePass=<container password>
davmail.ssl.keyPass=<secret key password>
More importantly, enable the headless version to authenticate to EWS. therefore replace davmail.enableEws=auto
with
davmail.enableEws=EWS
davmail.authenticator=davmail.exchange.auth.O365Authenticator
davmail.oauth.<user@email.tld>.refreshToken={AES}...
If you want to proxy multiple users, add a line for each.
Run the server with
docker-compose up -d
Authentication problems
The login page at https://login.microsoftonline.com/ has a different oauth flow depending on your user agent. To get the simplest flow, pretend to not be a browser with e.g.
davmail.userAgent=python-requests/2.31.0
Warning
This user agent is also used for the login page of a possible ADFS. Your friendly administrator may ask you about suspicious non browser logins.
Clients
To connect clients to the new server, you need the correct settings as there is no autoconfiguration available. As server address it is always the one you used for the certificate creation. As username, use your full email, and the correct password.
Protocol | Port | Config |
---|---|---|
IMAP | 1143 | enable TLS (not STARTTLS) and cleartext auth |
SMTP | 1025 | enable TLS, plain auth |
CaDav | https://server.domain:1080/ | make sure to use https |
Troubleshooting: K9 Mail on Android
When setting up the mail account on K-9 mail or its derivatives, it fails because of an unsupported IMAP command. This is resolved by creating a new empty folder named SPECIAL-USE
through the Outlook web interface.
Troubleshooting: Kmail Timeout
Kmail has a very short timeout on fetching messages. For large messages, davmail is not fast enough to fetch the message via http before kmail times out. A workaround is to let davmail cache messages with
davmail.folderSizeLimit=1000000