Email with Microsoft Exchange Accounts on Linux

(5 minutes | 1049 words | )

Summary

Email is one of the most efficient ways of communication if done right. Most people appreciative to email value a specific set of tools that help streamline the email process. Most often, email is fetched on a device using the POP or IMAP protocol. Some institutions may use different protocols that are not always supported by said tools and/or operating system. This post details the steps necessary for me to fetch email via the POP protocol from a Microsoft Exchange account using the Davmail gateway on a Linux system.

Table of Contents


Introduction

My workflow is command-line driven and the tools I use to process email are either local daemons, scripts or some ncurses based application. Conceptually, my email data flow looks like this:

Mail ServerslocalhostprocmailgetmailspamassassinMaildirmuttmuuser scriptsdavmailMDAPOP3POP3SMTPMicrosoft ExchangeTrusted Remote Server

A new account required communication with a Microsoft Exchange server on which the IT department disabled POP and IMAP protocols. Since neither getmail nor mutt know how to do that, the additional davmail node in the diagram above was required to be added. Davmail runs as a daemon that enables POP and SMTP protocols on the localhost which it then translates to the Microsoft Exchange protocol. Apart from POP and SMTP, Davmail also supports IMAP, LDAP, CalDav and CardDav protocols. With the Davmail proxy in place, any application that is using these protocols can communicate with a server that is using the Microsoft Exchange protocol.

Davmail Configuration

The following configuration is intended to use Davmail as a server daemon mainly using POP, SMTP and CalDav protocols. Currently evolution-ews is one of the few email client implementations on Linux that work with Microsoft Exchange services. The IT department which manages the Microsoft Exchange server I am connecting to supports this application and typically there is a high level of resistance when asked to support another one.

Authentication on the remote is done with OAuth2. Following the path of least resistance, I am using the clientId and tenantId intended for evolution-ews. This information can typically be found on the help pages provided by the IT department. The persistToken flag (its default value is true) will append a refresh token at the end of the properties file after connecting to the remote server for the first time. The token will be used for automatic authentication for subsequent connections to the server. The steps to obtain a refresh token are the following:

  1. If davmail is already running as a daemon, use systemctl to stop the service.
  2. Set davmail.mode=O365Manual in your davmail properties file.
  3. Run davmail manually with the properties file as argument.
  4. Force a connection on the port davmail is listening, for example by fetching mail or sending an email with msmtp.
  5. Follow the instructions in the stdout found in the terminal where davmail was started.
  6. Set davmail.mode=O365Modern in your davmail properties file and restart the systemd service. From now on authentication happens via the token that has been appended in the properties file used in item 2.

By default, communication with the local Davmail daemon is not encrypted which is fine in most cases (it can be changed if desired, see the documentation).

Since local communication is not encrypted, you would technically not need a password when authenticating with Davmail. Nevertheless, you should still use a password when connecting to Davmail with your local applications. Davmail will use this password to encrypt the refresh token with a symmetric AES cipher before it is written to the properties file (you have to use the same password with all your local applications for this to work). Additionally, you may want to change the file access permissions of the properties file for further security measures.

The listener ports can be chosen freely from the available user ports. For initial setup and testing, the logging level in line 51 may need to be set to DEBUG. In order to get a refresh token, you will need to paste an access code that is obtained from the Microsoft Exchange server back into Davmail. To achieve this, execute Davmail directly from the command-line with a properties file argument where the mode is set to O356Manual. Once the initial connection was successful the refresh token will be appended to the file and the mode can be set back to O356Modern for subsequent automatic authentication running Davmail as a systemd user service.

 1# server and mode settings
 2davmail.server=true
 3davmail.enableKeepAlive=true
 4# STEPS:
 5# 0. Adjust davmail.logFilePath below.
 6# 1. Use O365Manual for initial connection (this should append a refresh token
 7#    to this file, davmail must be executed from the command line).
 8# 2. Use O365Modern for headless server (e.g. systemd service) operation.
 9#    Obtaining an access token should now be automated until refresh token
10#    expires.
11davmail.mode=O365Manual
12# davmail.mode=O365Modern
13davmail.url=https://outlook.office365.com/EWS/Exchange.asmx
14
15# oauth evolution mock settings
16davmail.oauth.clientId=<client id>
17davmail.oauth.tenantId=common
18davmail.oauth.redirectUri=https://login.microsoftonline.com/common/oauth2/nativeclient
19davmail.oauth.persistToken=true
20
21# listener ports
22davmail.caldavPort=5000
23davmail.popPort=5001
24davmail.imapPort=5002
25davmail.ldapPort=5003
26davmail.smtpPort=5004
27
28# network proxy settings
29davmail.enableProxy=false
30davmail.useSystemProxies=false
31davmail.allowRemote=false
32
33# disable SSL for specified listeners
34davmail.ssl.nosecurecaldav=false
35davmail.ssl.nosecureimap=false
36davmail.ssl.nosecureldap=false
37davmail.ssl.nosecurepop=false
38davmail.ssl.nosecuresmtp=false
39
40# POP settings
41davmail.keepDelay=0
42davmail.sentKeepDelay=0
43davmail.popMarkReadOnRetr=false
44
45# SMTP settings
46davmail.smtpSaveInSent=false
47
48# logging
49davmail.logFilePath=/path/to/logfile
50log4j.rootLogger=WARN
51log4j.logger.davmail=INFO
52
53# davmail appended items

Patching Davmail for Forced Message Deletion on Remote

I prefer POP to permanently delete messages when successfully fetched such that none of my email resides on external mail servers (on mobile devices I typically use IMAP to receive messages while on the go). Also note that smtpSaveInSent is set to false in the Davmail configuration above which will prevent saving a copy of sent mail on the server. Default Davmail code is conservative and moves messages to trash when it receives the DELE command via POP (which is probably the sensible thing to do in most cases). Permanent message deletion on the server can be enforced by applying this patch to the source code. For Arch Linux users, an AUR package that applies this patch during build can be obtained with

1git clone https://git.0xfab.ch/davmail-git.git

SMTP Configuration in Mutt

Local communication with Davmail is not encrypted and SMTP configuration in clients such as mutt must be setup accordingly. In particular, SSL settings must be disabled for the account that connects to Davmail:

1set ssl_starttls  = "no"
2set ssl_force_tls = "no"
3set smtp_url      = "smtp://<username>@localhost:<davmail smtp port>/"

→ please send an email to the mailing list for comments (using post title as subject).
→ click here to see all comments.
→ mailing list etiquette.
tags: davmaillinuxmicrosoftemail;