-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for XOAUTH2 authorization, and documented in base.pod #44
base: develop
Are you sure you want to change the base?
Conversation
EDIT: Presently DMS recently added support for these in Dovecot with the v13.3 release.
Offline test environment with Docker Compose + DMSIf you need a popular production instance to test against, DMS makes this simple (it already bundles the latest # Normally this would provide TLS configured for both services, that's been omitted to keep the reproduction simple
services:
# Quick and easy mailserver setup with Postfix + Dovecot for testing OAuth2 support
dms:
image: docker.io/mailserver/docker-mailserver:13.3
container_name: dms-mail
hostname: mail.example.test
environment:
# Enable the OAuth2 support in Dovecot and configure it for our mocked service (caddy):
ENABLE_OAUTH2: 1
OAUTH2_INTROSPECTION_URL: http://auth.example.test/userinfo/
# Test authentication against these ports:
ports:
- "143:143" # IMAP STARTTLS (Dovecot)
- "587:587" # SMTP STARTTLS (Postfix)
configs:
- source: dms-accounts
target: /tmp/docker-mailserver/postfix-accounts.cf
# This would normally be a proper auth service, this is sufficient to mock out the required behaviour for testing
caddy-oauth2:
image: caddy:2.7
container_name: dms-oauth2
# Leverage Docker's internal DNS for the private network bridge it creates between services:
hostname: auth.example.test
ports:
- "80:80"
configs:
- source: mock-auth-service
target: /etc/caddy/Caddyfile
# Using the Docker Compose `configs.content` feature instead of volume mounting separate files.
# NOTE: This feature requires Docker Compose v2.23.1 (Nov 2023) or newer:
# https://github.com/compose-spec/compose-spec/pull/446
configs:
# Basic Caddyfile example, see a better documented equivalent at:
# https://github.com/docker-mailserver/docker-mailserver/blob/v13.3.0/test/config/oauth2/Caddyfile
mock-auth-service:
content: |
:80 {
@auth header Authorization "Bearer DMS_YWNjZXNzX3Rva2Vu"
handle @auth {
respond `{ "email": "[email protected]", "email_verified": true }`
}
# Otherwise fail when expected auth header and value were not matched:
respond 401 {
close
}
}
# DMS expects an account to be configured to run, this config provides one
# You can add new accounts with `docker compose exec dms setup email add [email protected] bad-password`
# Login credentials:
# user: "[email protected]" password: "secret"
# user: "[email protected]" password: "secret"
dms-accounts:
# NOTE: `$` needed to be repeated to escape it,
# which opts out of the `compose.yaml` variable interpolation feature.
content: |
[email protected]|{SHA512-CRYPT}$$6$$sbgFRCmQ.KWS5ryb$$EsWrlYosiadgdUOxCBHY0DQ3qFbeudDhNMqHs6jZt.8gmxUwiLVy738knqkHD4zj4amkb296HFqQ3yDq4UXt8.
[email protected]|{SHA512-CRYPT}$$6$$o65y1ZXC4ooOPLwZ$$7TF1nYowEtNJpH6BwJBgdj2pPAxaCvhIKQA6ww5zdHm/AA7aemY9eoHC91DOgYNaKj1HLxSeWNDdvrp6mbtUY. CommandsGenerate the auth strings with base64 encoding via CLI if necessary: These base64 encoded values will appear in the SMTP protocol exchange as part of SMTP `AUTH` / IMAP `AUTHENTICATE` commands# In DMS Postfix delegates SMTP AUTH to Dovecot via SASL
# Dovecot expects to receive the XOAUTH2 / OAUTHBEARER auth string encoded as base64,
# which it decodes and verifies the bearer token at the configured OAuth2 service endpoint (eg: `/userinfo`)
# via an HTTP request with an Authorization header (of Bearer type).
# Encoding the XOAUTH2 auth string as base64:
$ echo -en '[email protected]\001auth=Bearer DMS_YWNjZXNzX3Rva2Vu\001\001' | base64 -w0; echo
dXNlcj1qb2huLmRvZUBleGFtcGxlLnRlc3QBYXV0aD1CZWFyZXIgRE1TX1lXTmpaWE56WDNSdmEyVnUBAQ==
# OAUTHBEARER equivalent:
$ echo -en 'n,[email protected],\001host=localhost\001port=143\001auth=Bearer DMS_YWNjZXNzX3Rva2Vu\001\001' | base64 -w0; echo
bixhPWpvaG4uZG9lQGV4YW1wbGUudGVzdCwBaG9zdD1sb2NhbGhvc3QBcG9ydD0xNDMBYXV0aD1CZWFyZXIgRE1TX1lXTmpaWE56WDNSdmEyVnUBAQ==
# Equivalent values for [email protected] with the same Access Token
# XOAUTH:
dXNlcj1qYW5lLmRvZUBleGFtcGxlLnRlc3QBYXV0aD1CZWFyZXIgRE1TX1lXTmpaWE56WDNSdmEyVnUBAQ==
# OAUTHBEARER:
bixhPWphbmUuZG9lQGV4YW1wbGUudGVzdCwBaG9zdD1sb2NhbGhvc3QBcG9ydD0xNDMBYXV0aD1CZWFyZXIgRE1TX1lXTmpaWE56WDNSdmEyVnUBAQ== Test commands (run on the host system after a # Testing against the mocked endpoint directly (which is what Dovecot is responsible for handling):
# - Within the DMS container this would be to http://auth.example.test/userinfo
# - Otherwise from the host system reach the caddy container via the published port on localhost
# In this case Dovecot is configured by default to validate successful auth by matching the
# returned `email` field against the `user` field (provided via the auth string).
curl http://localhost:80/userinfo -H 'Authorization: Bearer DMS_YWNjZXNzX3Rva2Vu' -w '\n'
# Response: { "email": "[email protected]", "email_verified": true }
# Testing through Postfix SMTP AUTH via the proposed swaks options of this PR:
# `swaks` is also available within the container (at `/usr/local/bin/swaks`),
# use it via `docker compose exec dms swaks ...`
swaks --server localhost:587 \
--from [email protected] \
--to [email protected] \
--auth XOAUTH2 \
-au [email protected] \
-ap DMS_YWNjZXNzX3Rva2Vu For comparison here is the equivalent with curl: # Set `--login-options` to either 'AUTH=XOAUTH2' or 'AUTH=OAUTHBEARER'.
# Both are valid and the DMS container logs from Postfix will indicate the correct method like:
# `sasl_method=OAUTHBEARER, [email protected]`
# The curl output itself also shows authentication success during the SMTP protocol.
#
# NOTE: If running on the host replace `mail.example.test` with `localhost`.
# NOTE: Technically `--upload-file` expects a proper input with RFC 5322 headers:
# https://everything.curl.dev/usingcurl/smtp
curl --silent --verbose \
--url 'smtp://mail.example.test:587' \
--user '[email protected]' \
--login-options 'AUTH=XOAUTH2' \
--oauth2-bearer 'DMS_YWNjZXNzX3Rva2Vu' \
--mail-from '[email protected]' \
--mail-rcpt '[email protected]' \
--upload-file <<< 'Hello Jane!' Output
NOTE: Instead of This security check can be ignored when performed within the DMS container and trust is given to mail clients running within that container by adding the ENV |
Hi John,
I've added and tested support for XOAUTH2 authorization protocol. Also added documentation, with Gmail as an example. The XOAUTH2 protocol requires an access token, and I am passing it via the -ap argument.
Tested it several times on my local machine.
Thanks,
Desirider.