<!--
.. title: Configure Mutt to work with OAuth 2.0
.. slug: configure-mutt-to-work-with-oauth-20
.. date: 2022-03-04 16:53:39 UTC
.. tags: mutt,oauth2,security,2FA
.. category: 
.. link: 
.. description: 
.. type: text
.. author: Dejice Jacob
-->


My email client of choice is [*mutt*](https://gitlab.com/muttmua/mutt). The keyboard short-cuts are
ingrained into muscle memory. I have tried to use complex passwords to keep myself secure. While that
may help, many large web service providers require the use of [OAuth 2.0](https://oauth.net/2) for better security. 

<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Mutt.png/320px-Mutt.png" 
 title="Mutt mail user agent (MUA)"
 alt="Mutt mail user agent (MUA)">
</img>

The fine *defenders of the galaxy* at [University of Glasgow IT](https://www.gla.ac.uk/it) 
started pushing for better security to access email and *office365* applications.  If Computer Scientists
do not lead the way on these things, what hope is there for the rest of digital society? 


### Introduction

[Peter van Ormondt](https://www.vanormondt.net/~peter/) wrote a simplified (*for dummies*) 
[guide](https://www.vanormondt.net/~peter/blog/2021-03-16-mutt-office365-mfa.html) that even I could understand. 
It worked first time on *Outlook365* and *GMail*. On GMail, I can now turn off "Less Secure Apps"[^lesssecure]
that annoyingly keeps getting switched off, if the method is not utilised regularly. 

A better understanding of how OAuth 2.0 has been implemented is explained in the OAuth 2.0 
[documentation](https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py.README) found in the mutt repo. 
While Mutt has native [OAuth2 support](http://www.mutt.org/doc/manual/#oauth), it provides a hook
to an external script to provide the authentication details. Conveniently, the Mutt project themselves have 
provided a Python script [`mutt_oauth2.py`](https://gitlab.com/muttmua/mutt/-/raw/master/contrib/mutt_oauth2.py)
to authorise  the user. The script keeps local state on a file which can be used to refresh the token. The 
`mutt_oauth2.py` script keeps this encrypted using `gpg`. 

### Configuration 
#### Configure and Authorise with [`mutt_oauth2.py`](https://gitlab.com/muttmua/mutt/-/raw/master/contrib/mutt_oauth2.py)

1. Create a separate `gpg` user to encrypt all the OAuth2 tokens for all providers. You could just as well re-use
one of your other GPG keys for this. 

        $ gpg --gen-key 
        GnuPG needs to construct a user ID to identify your key.
        
        Real name: My OAuth2 Token Encryption Key
        Email address: token.encryptor@oauth2.me
        You selected this USER-ID:
            "My OAuth2 Token Encryption Key <token.encryptor@oauth2.me>"
        
        Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
        We need to generate a lot of random bytes. It is a good idea to perform
        some other action (type on the keyboard, move the mouse, utilize the
        disks) during the prime generation; this gives the random number
        generator a better chance to gain enough entropy.

2. Download and install [`mutt_oauth2.py`](https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py)

        $ curl -o /any-path/mutt_oauth2.py https://gitlab.com/muttmua/mutt/-/raw/master/contrib/mutt_oauth2.py?inline=false
        $ chmod u+x /any-path/mutt_oauth2.py

3. Replace `YOUR_GPG_IDENTITY` with your *GPG* key in 
[`mutt_oauth2.py`](https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py#L47)
4. Our setup masquerades as the **Mozilla Thunderbird** e-mail client and utilizes their [`client-id` and `client-secret`](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm) 
   which is hard-coded into the client. The client secret is actually within the open-source repos of the Thunderbird client.
   You can also create your own credentials. See instructions for [GMail](#owncred).  The Thunderbird client registration 
   details as of today : 
       * [GMail](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm#l81): **client-id** - 
         [`406964657835-aq8lmia8j95dhl1a2bvharmfk3t1hgqj.apps.googleusercontent.com`](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm#l83), 
	 **client-secret** - [`kSmqreRr0qwBWJgbf5Y-PjSU`](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm#l84)
       * [Microsoft](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm#l127): **client-id** - 
         [`08162f7c-0fd2-4200-a84a-f25a4db0b584`](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm#l129),
	 **client-secret** - [`TxRBilcHdC6WGBee]fs?QR:SJ8nI[g82`](https://hg.mozilla.org/comm-central/file/tip/mailnews/base/src/OAuth2Providers.jsm#l130)

5. Intial authorisation for this client should be executed as: `/any-path/mutt_oauth2.py /any-path/oath2_token_file --authorize`. There should be a separate file for each email provider. When requested to input *authorisation flow* or *authentication method*, `localhostauthcode` will store the file in the same path. This is a one time operation and will be valid as long as the **oauth2_token_file** is available. You can delete the file and do the authorisation again if you so desire. Executing this script will provide a URL to paste into a browser. After opening the link in the browser and finishing any requisite authorisation, the script will obtain a token, encrypt it with your *GPG* key and store it locally in the path you have chosen.

#### Configure `.mutt` config
Add the following entries to the `.mutt` config file for **OAUTH2** authentication. 
```
set imap_authenticators = "oauthbearer:xoauth2"
set imap_oauth_refresh_command = "/any-path/mutt_oauth2.py /any-path/oath2_token_file"
set smtp_authenticators = ${imap_authenticators}
set smtp_oauth_refresh_command = ${imap_oauth_refresh_command}
```
`xoauth2` was the experimental authentication protocol which got standardised as `oauthbearer`. However, it seems that while 
GMail seems to work with `oauthbearer`, Microsoft still requires `xoauth2`. 

#### <a name="owncred"></a> Roll your own Client credentials for GMail
1. Login to your google account, and navigate to your developer console to generate 
[OAuth 2.0 credentials](https://console.cloud.google.com/apis/credentials)
2. Navigate to the "*Credentials*" page and click on `+ Create Credentials` to create an OAuth client ID. 

This `client-ID` and `client-secret` can then be used in the `mutt_oauth2.py` script. 


[^lesssecure]: I fear the long term consequences of cajoling users by using manipulative language 
such as this.  It will cause a loss of credibility for experts in the long run. 
Regaining trust that is once lost crying "Wolf" will only happen after a period 
of difficult consequences for both expert and layperson.  
