This document describes how I can read mail without relying on the outlook web interface, or Mac's mail app. This is somewhat complex because the university mail uses Microsoft exchange.
Mainly, the information below is compiled from this blog post, which describes davmail, and this post, which describes mu4e (emacs) configuration.
I got all of the software from brew.
The packages required are davmail, isync (which provides the mbsync executable), msmtp, and mu.
davmail is a program which acts as a proxy between Microsoft Exchange and IMAP/SMTP.
The local machine's mail client connects to a local IMAP/SMTP server controlled by davmail, so that it doesn't have to talk to Exchange directly.
davmail has a configuration file, which is, in my case, at ~/.davmail.properties.
Its contents are as follows:
# Disallow access to the davmail server from remote hosts (i.e., # other computers on the network) davmail.allowRemote=false # Don't use SSL (between email client and davmail) davmail.ssl.nosecurecaldav=false davmail.ssl.nosecureimap=false davmail.ssl.nosecureldap=false davmail.ssl.nosecuresmtp=false # The ports to run the different services on. You'll need # these to connect clients. davmail.caldavPort=6000 davmail.imapPort=6001 davmail.ldapPort=6002 davmail.smtpPort=6003 # Connection details for your exchange account. Odds are good # that the url listed here will work for you. If not, see if your # University/employer has any details on the correct host URL to # connect to their email services with. davmail.url=https://outlook.office365.com/EWS/Exchange.asmx # Set the authentication mode to manual davmail.mode=O365Manual # Run davmail in server mode davmail.server=true davmail.enableKeepAlive=true
Once a program, like mbsync, which reads mail into a local mailbox on your machine, connects to the IMAP server (which, again, is run locally through the proxy established by davmail), davmail reaches out via exchange, and will produce a URL.
This URL leads you through an authentication flow finally resulting in a blank page whose URL contains the authentication token.
Passing this URL back into davmail authenticates it with exchange.
Once it's authenticated, the aforementioned config file is modified with a line containing the token:
... # Run davmail in server mode davmail.server=true davmail.enableKeepAlive=true davmail.oauth.<my email>.refreshToken=<the token>...
In my case, there was one hitch, which is that the canonical input processing mode prevented me from pasting the entire token since it's so long. So, I had to disable canonical mode when running davmail, so that the token would be sent to the process in its entirety:
$ stty -icanon && davmail ~/.davmail.properties
mbsync is used to download mail from the mail server.
My configuration file is located at ~/.config/isyncrc, and its contents are as follows:
(I've replaced my actual account name with <account name> and my email with <my email>).
### University Email (using davmail) IMAPAccount <account name> Host 127.0.0.1 Port 6001 User <my email> PassCmd "security find-generic-password -a <my email> -s <my account name> -w" TLSType None AuthMechs LOGIN IMAPStore <account name>-remote Account <account name> MaildirStore <account name>-local Path ~/Mail/<account name>-mail/ Inbox ~/Mail/<account name>-mail/INBOX SubFolders Verbatim Channel <account name> Far :<account name>-remote: Near :<account name>-local: Patterns * SyncState * Create Both Sync All Expunge Near ### Gmail IMAPAccount gmail Host imap.gmail.com Port 993 TLSType IMAPS AuthMechs LOGIN # <-- Note this line User <my gmail>@gmail.com PassCmd "security find-generic-password -a <my gmail>@gmail.com -s <my gmail> -w" IMAPStore gmail-remote Account gmail MaildirStore gmail-local Path ~/Mail/gmail-mail/ Inbox ~/Mail/gmail-mail/INBOX SubFolders Verbatim Channel gmail Far :gmail-remote: Near :gmail-local: Patterns * SyncState * Create Both Sync All Expunge Near
PassCmd is a command to run to find your account password.
We can use macOS' security command to call up the password from keychain when it's required, rather than writing it in plain text in the configuration file.
Note that in the case of Gmail, the password stored in the keychain is an application password, since google does not permit IMAP authentication using your account password.
Adding AuthMechs LOGIN was also necessary to get authentication to work (see this blog post).
Running mbsync <account name> will sync the local mail directory specified as above with the server.
Passing -a will cause all accounts to be synchronized.
msmtp is used to send mail. It's configuration (~/.msmtprc) is as follows:
defaults logfile ~/Mail/msmtp.log tls_trust_file system # Use the system's tls certificate ### University Email account <account name> host 127.0.0.1 port 6003 protocol smtp auth plain tls off user <my email> from <my email> passwordeval "security find-generic-password -a <my email> -s <my account name> -w" ### Gmail account gmail auth on host smtp.gmail.com port 465 protocol smtp from <my gmail>@gmail.com user <my gmail>@gmail.com passwordeval "security find-generic-password -a <my gmail>@gmail.com -s <my gmail> -w" tls on tls_starttls off # Default account default : <account name>