Michele Marcionelli - Head of IT at D-MATH

Mutt, fetchmail & Co. with Exchange Online

Note: this how-to is not officially supported by the central IT services of the ETH.

With the Email OAuth 2.0 Proxy it's "easily" possible to access your e-mails also with command-line tools, like fetchmail, mutt, pine, emacs... This howto illustrate for instance the access with fetchmail & mutt.

Install and configure the e-mail proxy

First install the emailproxy, which is a Python module, with its dependencies as follow:

python -m pip install emailproxy

Then configure it as follow. In the code below just replace "your-eth-username" with your ETH username:

cat << EOF > emailproxy.config
[IMAP-1993]
server_address = outlook.office365.com
server_port = 993
local_address = 127.0.0.1

[SMTP-1587]
server_address = smtp.office365.com
server_port = 587
server_starttls = True
local_address = 127.0.0.1

[your-eth-username@ethz.ch]
permission_url = https://login.microsoftonline.com/common/oauth2/v2.0/authorize
token_url = https://login.microsoftonline.com/common/oauth2/v2.0/token
oauth2_scope = https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access
redirect_uri = https://login.microsoftonline.com/common/oauth2/nativeclient
client_id = 9e5f94bc-e8a4-4e73-b8be-63364c29d753
client_secret = 

[emailproxy]
delete_account_token_on_password_error = False
EOF

Note: the client_id that you see above is the one of Thunderbird, wich seems to be commonly be (mis)used by other apps.

Start the proxy

$(python -m site --user-base)/bin/emailproxy --no-gui --external-auth
==>
2024-06-26 07:59:17: Initialising Email OAuth 2.0 Proxy (version 2024-05-25) from config file /Users/username/emailproxy.config
2024-06-26 07:59:17: Starting IMAP server at 127.0.0.1:1993 (unsecured) proxying outlook.office365.com:993 (SSL/TLS)
2024-06-26 07:59:17: Starting SMTP server at 127.0.0.1:1587 (unsecured) proxying smtp.office365.com:587 (STARTTLS)
2024-06-26 07:59:17: Initialised Email OAuth 2.0 Proxy - listening for authentication requests. Connect your email client to begin

As you see from the output you now need to connect your e-mail client to begin.

General configuration

The general client configuration is:

fetchmail configuration

A sample configuration for fetchmail that also use procmail as MDA to just download your e-mails, is the following (replace your "your-eth-username" below):

cat << EOF > ~/.fetchmailrc
server 127.0.0.1
port 1993
proto IMAP
user 'your-eth-username@ethz.ch'
fetchall
keep
# fetchmail 7
#sslmode none
# fetchmail 6
no sslcertck
folder INBOX
mda "procmail -f %F -m .procmailrc"
EOF

cat << EOF > ~/.procmailrc 
:0
*
inbox/
EOF

Note: here we have to disable SSL for the local connection, but the connection between the proxy and the server is still encrypted

mutt configuration

A sample configuration for mutt that allow you to read and write (send) e-mail – update the imap_user, the realname and the from accordingly:

cat << EOF > ~/.muttrc
# mutt config with e-mail proxy
set hostname                   = "ethz.ch"
set imap_user                  = "your-eth-username@ethz.ch"
set realname                   = "Firstname Lastname"
set from                       = "${realname} <${imap_user}>"
set folder                     = "imap://localhost:1993"
set smtp_url                   = "smtp://${imap_user}@localhost:1587"
set spoolfile                  = "=inbox"
set record                     = "=Sent Items"
set ssl_force_tls              = no
set ssl_starttls               = no
EOF

The first run

Example with fetchmail

The first time that you connect your client to the e-mail proxy, you have to enter a password. This password is not your e-mail password and can be anything you like, and does not need to be the one you actually use to log in to your account (though it must be the same value each time, or you will be asked to re-authenticate repeatedly by the proxy). The password you provide is used only to encrypt and decrypt the OAuth 2.0 authentication token that the proxy transparently sends to the server on your behalf (this will be saved into the emailproxy.config file).

Execute:

fetchmail
==>
Enter password for username@ethz.ch@127.0.0.1: ******

Then in the terminal where you started the e-mail proxy you should see something like this:

2024-06-26 07:59:35: Accepting new connection from [::ffff:127.0.0.1]:59370 to IMAP server at 127.0.0.1:1993 (unsecured) proxying outlook.office365.com:993 (SSL/TLS)
2024-06-26 07:59:36: Authorisation request received for username@ethz.ch (external auth mode)
2024-06-26 07:59:36: Email OAuth 2.0 Proxy No-GUI external auth mode: please authorise a request for account username@ethz.ch

Copy+paste or press [↵ Return] to visit the following URL and authenticate account username@ethz.ch:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=.....
then paste here the full post-authentication URL from the browser's address bar (it should start with https://login.micro
softonline.com/common/oauth2/nativeclient):

and at the same time a browser window opens and ask you to authenticate:

Finally you get a blank page (as described above). Just copy the whole URL (that will have a ?code= in it) and paste it in the terminal where you started the e-mail proxy. Then you should see this:

2024-06-26 08:01:00: IMAP (127.0.0.1:1993; username@ethz.ch) [ Successfully authenticated IMAP connection - releasing session ]

and the e-mail will be downloaded (with an output like this):

12 messages for username@ethz.ch at 127.0.0.1 (folder INBOX).
reading message username@ethz.ch@127.0.0.1:1 of 12 (1808 header octets) (7265 body octets) not flushed
reading message username@ethz.ch@127.0.0.1:2 of 12 (1713 header octets) (54897 body octets) not flushed
[...]

Normal use

The e-mail proxy must always be running, so consider creating a service file that starts at boot or login (see 2nd link below for an example). Then just start your e-mail client and login with the password defined in the step "first run".

See also