imap,smtp: add XOAUTH2 support

Add XOAUTH2 authentication support for IMAP and SMTP. Although XOAUTH2
is now deprecated in favor of OAuthBearer, it is the only way to connect
to Office365 since Basic Auth is now completely removed.

Since XOAUTH2 is very similar to OAuthBearer and uses the same
configuration parameters, this is basically a copy-paste of the existing
OAuthBearer code.

However, XOAUTH2 support was removed from go-sasl library, so this
change reimports the code that was removed from go-sasl and offers it
a new home in lib/xoauth2.go. Hopefully it shouldn't be too hard to
maintain, being less than 50 SLOC.

Link: 7bfe0ed36a
Implements: https://todo.sr.ht/~rjarry/aerc/78
Signed-off-by: Julian Pidancet <julian.pidancet@oracle.com>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
Julian Pidancet 2022-09-28 19:49:11 +02:00 committed by Robin Jarry
parent 45bff88515
commit 9217dbeea4
8 changed files with 142 additions and 2 deletions
commands/compose

View file

@ -302,6 +302,28 @@ func newSaslClient(auth string, uri *url.URL) (sasl.Client, error) {
Username: uri.User.Username(),
Token: password,
})
case "xoauth2":
q := uri.Query()
oauth2 := &oauth2.Config{}
if q.Get("token_endpoint") != "" {
oauth2.ClientID = q.Get("client_id")
oauth2.ClientSecret = q.Get("client_secret")
oauth2.Scopes = []string{q.Get("scope")}
oauth2.Endpoint.TokenURL = q.Get("token_endpoint")
}
password, _ := uri.User.Password()
bearer := lib.Xoauth2{
OAuth2: oauth2,
Enabled: true,
}
if bearer.OAuth2.Endpoint.TokenURL != "" {
token, err := bearer.ExchangeRefreshToken(password)
if err != nil {
return nil, err
}
password = token.AccessToken
}
saslClient = lib.NewXoauth2Client(uri.User.Username(), password)
default:
return nil, fmt.Errorf("Unsupported auth mechanism %s", auth)
}