A Headless Office 365 Proxy# Nov 9, 2022
As I mentioned in my last
post, I’ve been
experimenting with replacing
davmail with Simon Robinson’s super-cool
mutt up to it. As before, here’s a specific rundown of
how I configured O365 access using this.
We need some small tweaks to the shipped configuration file. It’s used for both permanent configuration and acquired tokens, but the static part looks something like this:
[[email protected]] 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.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/POP.AccessAsUser.All https://outlook.office365.com/SMTP.Send offline_access redirect_uri = https://login.microsoftonline.com/common/oauth2/nativeclient client_id = facd6cff-a294-4415-b59f-c5b01937d7bd client_secret =
Updated 2022-11-22: you also want to set
False: I’m a bit bemused on why anyone would ever want this to be set to
True, and unfortunately, that’s the default.
fetchmail as follows:
poll localhost protocol IMAP port 1993 auth password username "[email protected]" is localuser here keep sslmode none mda "/usr/bin/procmail -d %T" folders INBOX
mutt like this:
set smtp_url = "smtp://[email protected]@localhost:1587/" unset smtp_pass set ssl_starttls=no set ssl_force_tls=no
When you first connect, you will get a GUI pop-up and you need to interact with the tray menu to follow the authorization flow. After that, the proxy will refresh tokens as necessary.
Running in systemd
service file I use, slightly modified from the upstream’s README:
$ cat /etc/systemd/system/emailproxy.service [Unit] Description=Email OAuth 2.0 Proxy [Service] ExecStart=/home/localuser/src/email-oauth2-proxy/emailproxy.py --external-auth --no-gui --config-file /home/localuser/src/email-oauth2-proxy/my.config Restart=always [Install] WantedBy=multi-user.target
In the upstream project, only initial authorizations require the GUI.
Unfortunately, for truly headless operation, things are a bit more complicated.
In theory, you can use the
--local-server-auth with a localhost
redirect-uri, but this is awkward enough to use that it seems useless: the
README talks vaguely about log monitoring, and this hack isn’t permitted by
The maintainer isn’t interested in supporting headless in any other way, so I have a fork with this in my no-gui-external branch.
This does what
davmail does when an authorization is needed, like this:
$ sudo systemctl stop emailproxy $ ./emailproxy.py --no-gui --config-file /home/localusr/src/email-oauth2-proxy/my.config --external-auth # Now connect from mutt or fetchmail 2022-11-09 23:44:25: Authorisation request received for [email protected] (interactive mode) Please visit the following URL to authenticate account [email protected]: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=... Please paste the full resulting redirection URL: # ... 2022-11-09 23:44:42: SMTP (localhost:1587; [email protected]) [ Successfully authenticated SMTP connection - releasing session ] ^C $ sudo systemctl start emailproxy
Obviously, you’ll need to do this interactively from the terminal, then restart in daemon mode.
So far this is working well for me, but it’s certainly ugly. I wish there a better way to do this…