Skip to content
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

[Feature Request] Support SASL XOAUTH2 for relay traffic #1062

Open
cruvolo opened this issue May 21, 2020 · 15 comments
Open

[Feature Request] Support SASL XOAUTH2 for relay traffic #1062

cruvolo opened this issue May 21, 2020 · 15 comments

Comments

@cruvolo
Copy link

cruvolo commented May 21, 2020

Please consider support for outgoing SASL XOAUTH2 authentication for relay traffic. This seems required for gmail auth where password auth and "app passwords" are disabled. More here about gmail-specific implementation:

https://developers.google.com/gmail/imap/xoauth2-protocol#smtp_protocol_exchange

Thank you.

@DemiMarie
Copy link
Contributor

Obtaining an OAuth token is almost certainly out of scope for this project.

@poolpOrg
Copy link
Member

Yes, @DemiMarie is right, there's no chance OAuth makes it into the daemon.

However, it may be interesting to consider how this could be implemented outside of the daemon, in a filter for instance.

@DemiMarie
Copy link
Contributor

DemiMarie commented Jun 1, 2020

From what I can tell, the only change needed to OpenSMTPD is allowing the complete authentication command to be overridden.

Edit: This works not just for OAuth2, but also for most other forms of authentication. The main exception I can think of is Kerberos/NTLMv2 with channel binding, which needs access to the TLS session to compute the auth command.

@andreyrusanov
Copy link

Having SASL support as an option would be definitely amazing, because just tables at filesystem is not enough unfortunately.

@DemiMarie
Copy link
Contributor

Authentication only needs to happen when a new session is opened, which is likely to be infrequent. Therefore, I suggest allowing a filter (run as a separate, non-privileged user) to handle the entire authentication sequence itself.

@azmeuk
Copy link

azmeuk commented Sep 15, 2021

Dovecot supports OAuth2 authentication, so if Dovecot SASL support was implemented, this could be a way to indirectly support OAuth2 in OpenSMTPD (if you use Dovecot as your MDA).

@azmeuk
Copy link

azmeuk commented Sep 16, 2021

I just blindly tried to authenticate with XOAUTH2 and this generated this kind of logs:

Sep 16 10:04:54 xxx mail.info smtpd-pam[33031]: 775bbad3d82268bc smtp connected address=[xxxx:xxxx::x] host=xxxx.xxxx.xx
Sep 16 10:04:54 xxx mail.info smtpd-pam[33031]: 775bbad3d82268bc smtp tls ciphers=TLSv1.3:TLS_AES_256_GCM_SHA384:256
Sep 16 10:04:54 xxx mail.info smtpd-pam[33031]: 775bbad3d82268bc smtp failed-command command="AUTH XOAUTH2 dXNlcj1lbG9pQHlhYWwuY29vcAFhdXRoPUJlYXJlciBsaDZFY2NwT3lYcEJRSGNlN3B0ZDFpazQ1WmdlRldGc0hjSDltVkUzeTIBAQ==" result="504 5.7.4 Security features not supported: AUTH method "XOAUTH2" not supported"
Sep 16 10:04:54 xxx mail.info smtpd-pam[33031]: 775bbad3d82268bc smtp disconnected reason=quit

I can see that the error message is raised by this piece of code:

if (strcasecmp(method, "PLAIN") == 0)
smtp_rfc4954_auth_plain(s, eom);
else if (strcasecmp(method, "LOGIN") == 0)
smtp_rfc4954_auth_login(s, eom);
else
smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported",
esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED),
esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED),
method);

So, the only available auth methods are PLAIN and LOGIN. @DemiMarie are you sure that writing a filter would be engough? Would it prevent this piece of code to be executed? I would like to write a POC for this, do you have any piece of advice? For instance would recommend to use the deprecated filter-python as a base to do this?

@DemiMarie
Copy link
Contributor

So, the only available auth methods are PLAIN and LOGIN. @DemiMarie are you sure that writing a filter would be engough? Would it prevent this piece of code to be executed? I would like to write a POC for this, do you have any piece of advice? For instance would recommend to use the deprecated filter-python as a base to do this?

It would not be enough; my proposal was to change the C source so as to make this possible. Dovecot SASL would be a good way to start.

@molo1134
Copy link

Would it prevent this piece of code to be executed?

This code is for incoming connections, yes? This issue was opened for outgoing relay connections.

@dimpase
Copy link

dimpase commented Dec 5, 2022

Please consider support for outgoing SASL XOAUTH2 authentication for relay traffic. This seems required for gmail auth

since quite some years ago I am able to use postfix to authenticate to gmail as an outgoing relay, with 2FA enabled. This requires getting one of their "App passwords" - one you can use instead of the regular password + 2FA token.

It seems this should work with OpenSMTPD, cf. smtpd.conf(5).

@cruvolo
Copy link
Author

cruvolo commented Dec 5, 2022

This issue was opened specifically for support when app passwords were disabled (e.g. by an organization's IT policy). Please see the original request.

for gmail auth where password auth and "app passwords" are disabled

@dimpase
Copy link

dimpase commented Dec 5, 2022

Excuse my ignorance, but isn't this authentication mechanism still needing a password (thus, an app password) anyway?

@dimpase
Copy link

dimpase commented Dec 5, 2022

Anyway, the following might be helpful (it's postfix-specific, though): https://github.com/tarickb/sasl-xoauth2

@bzp99
Copy link

bzp99 commented Feb 15, 2023

@poolpOrg:

However, it may be interesting to consider how this could be implemented outside of the daemon, in a filter for instance.

Would this really be possible with filters? I have experimented with them a little just now and it seems they are able to intercept parts of the exchange between the client and smtpd and not smtpd and the relay host when actually relaying the mail.

It would be relatively easy to accomplish XOAUTH2 authentication when relaying if there was a way to add some form of a hook that allows one to change how smtpd authenticates itself to the remote host. For example, I am thinking about something like

action "outbound" relay host smtps:https://some-server.tld auth-external /path/to/script

Where script could simply provide on its standard output whatever smtpd shoud send to some-server.tld as part of the SMTP exchange right after the HELO/EHLO command. It could be as simple as

#!/bin/sh
echo AUTH PLAIN
echo [email protected]
echo s3cr3tp4ssw0rd

In the case of an actual XOAUTH2 auth script, it could start with echo AUTH XOAUTH2 and continue by sending the correct authentication information according to the spec. It is up to the user how the script works.

I don’t know how robust it would be like this. I am just brainstorming, kind of. Also wondering if I am missing something and this (or something close) is achievable by filters.

@toddfries
Copy link

toddfries commented Mar 1, 2023

https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online

So Microsoft has disabled ALL basic auth. Thanks to a helpful https://twitter.com/laurencetratt/status/1630669159343304704 tweet, I now have mbsync retrieving and smtpd sending mail via oauth2.

Side note:

  1. run this
    msmtpd --port=2525 --interface=::1
  2. add these to smtpd.conf
    action "relaymsmtp" relay host smtp:https://[::1]:2525
    ....
    match for any action "relaymsmtp"

In my case I only match for mail to a client or from the clients domain (me sending as an emailid on their server needs to relay through their server) .. so mine looks more like this:

   ....
   match for any mail-from <client> action "relaymsmtp"
   match from src <client> action "relaymsmtp"

   match for any action "relay"
  1. do something akin to this in /etc/msmtprc
    account default
    auth xoauth2
    host outlook.office365.com
    protocol smtp
    from [email protected]
    user [email protected]
    passwordeval pizauth show ms-johndoe
    port 587
    tls on
    tls_starttls on
    allow_from_override off
    set_from_header on
    syslog LOG_MAIL

  2. pkg_add -Ur cyrus-sasl-xoauth2

  3. do something akin to this in .mbsyncrc
    Create Both
    Expunge Both
    BufferLimit 50m

IMAPAccount ms-johndoe
Host outlook.office365.com
User [email protected]
PassCmd "pizauth show ms-johndoe"
SSLType STARTTLS
SSLVersions TLSv1.2
PipelineDepth 1
AuthMechs XOAUTH2

IMAPStore ms-johndoe-remote
Account ms-johndoe

MaildirStore ms-johndoe-local
Path ~/Mail/[email protected]/
Inbox ~/Mail/[email protected]/INBOX/
AltMap yes
SubFolders Verbatim

Channel ms-johndoe
Far :ms-johndoe-remote:
Near :ms-johndoe-local:
Patterns *
Sync Full
SyncState *

While its not native smtpd oauth2 support, it "works" ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants