help-gsasl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gsasl picks SCRAM PLUS-variant when channel binding data is not availab


From: Mechiel Lukkien
Subject: gsasl picks SCRAM PLUS-variant when channel binding data is not available and fails to authenticate
Date: 8 Jan 2024 17:30:11 +0100
User-agent: moxwebmail/0f8bf2f220887078d4f3b54efff643c93580e9ed+modifications

Hi,

I ran into a problem with mutt 2.2.12 (latest) on debian unstable, where it 
uses libgsasl (package 2.2.0-2), while testing the new SCRAM-SHA-{1,256}-PLUS 
support in my mail server mox (https://github.com/mjl-/mox). Mutt doesn't seem 
to support TLS channel binding: It doesn't set unique/exporter channel binding 
data properties, but gsasl still tries to use it by picking the SCRAM 
PLUS-variant, and then failing the authentication. I would expect gsasl to 
interpret "there is no channel binding data" as "scram client doesn't support 
the plus-variant" and thus to pick the bare scram variant. The gsasl 
authentication attempt now fails in mutt when both plus and bare scram 
mechanisms are available, which doesn't seem like the correct choice (also, 
mutt has suspect fallback behavior, I filed an issue report at the mutt repo, 
however it is currently hidden for being confidential).

I looked at lib/scram/ in gsasl, and it seems the first GSASL_CB_TLS_EXPORTER 
and GSASL_CB_TLS_UNIQUE checks are in _gsasl_scram_client_step, which I suspect 
is called for a SASL step, after the mechanism has been selected. But this is 
based on a very cursory look.

By the way, mox also announces PLUS support on the plaintext IMAP and 
submission ports. Another reason to treat "no channel binding data available" 
as "client does not support channel binding" [for this connection]. One can 
argue whether it makes sense to announce PLUS support on non-TLS connections. 
My rationale: If people connect to the plaintext IMAP/SMTP ports to see which 
auth mechanisms are implemented, I want them to see the PLUS variant and 
configure it for their TLS-protected connections. Also, listing SCRAM-*-PLUS 
just announces the server/service implements the PLUS variant, not whether it 
necessarily will succeed for the current connection (just like SCRAM-SHA-256 
can fail for some users because the server-side auth state hasn't been derived 
from the user password yet, e.g. after a server upgrade that introduced scram 
support but where users haven't (re)set their password).

I have tested against mox v0.0.8, that supports only the bare (non-PLUS) SCRAM 
variants. The SCRAM-*-PLUS support is in the latest commit, 
v0.0.9-0.20240105111555-c348834ce94a, and will be in v0.0.9 once released. 
These can be compiled into file "mox" in the current directory with (go version 
>= 1.20 required):

        GOBIN=$PWD CGO_ENABLED=0 go install github.com/mjl-/mox@v0.0.8

Or:

        GOBIN=$PWD CGO_ENABLED=0 go install 
github.com/mjl-/mox@v0.0.9-0.20240105111555-c348834ce94a

A local development mode, that starts an SMTP and IMAP server on localhost, 
ports standard+1000, and user/pass mox@localhost/moxmoxmox (more details 
printed on startup), can be started with:

        ./mox localserve


Using the gsasl cli tool against v0.0.9-0.20240105111555-c348834ce94a:

        $ gsasl --version
        gsasl (GNU SASL) 2.2.0

With "no channel binding" and without TLS connection, gsasl still tries to use 
channel binding and fails:

        $ gsasl --no-cb -a mox@localhost -p moxmoxmox --no-starttls --imap 
localhost 1143
        Trying ‘localhost’...
        * OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 
AUTH=SCRAM-SHA-1-PLUS AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STATUS=SIZE STARTTLS 
AUTH=PLAIN] mox imap
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1-PLUS 
AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID APPENDLIMIT=9223372036854775807 CONDSTORE 
QRESYNC STATUS=SIZE STARTTLS AUTH=PLAIN
        . OK CAPABILITY done
        . AUTHENTICATE SCRAM-SHA-256-PLUS
        . NO AUTHENTICATE cannot use plus variant with tls channel binding 
without tls
        gsasl: server error


Saying "no channel binding" with a TLS connection also fails. I would think 
should also be handled as "client doesn't support SCRAM-*-PLUS" and should 
choose SCRAM without PLUS:

        $ gsasl --x509-ca-file=$HOME/.config/mox-localserve/localhost.crt 
--no-cb -a mox@localhost -p moxmoxmox --imap localhost 1143
        Trying ‘localhost’...
        * OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 
AUTH=SCRAM-SHA-1-PLUS AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STATUS=SIZE STARTTLS 
AUTH=PLAIN] mox imap
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1-PLUS 
AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID APPENDLIMIT=9223372036854775807 CONDSTORE 
QRESYNC STATUS=SIZE STARTTLS AUTH=PLAIN
        . OK CAPABILITY done
        . STARTTLS
        . OK STARTTLS (lgGuOuQusGjsdopWzTu4tw) done
        TLS X.509 Verification: The certificate is trusted. 
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1-PLUS 
AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID APPENDLIMIT=9223372036854775807 CONDSTORE 
QRESYNC STATUS=SIZE AUTH=PLAIN
        . OK CAPABILITY done
        . AUTHENTICATE SCRAM-SHA-256-PLUS
        + 
        gsasl: mechanism error: Authentication failed because a tls-exporter 
channel binding was not provided.


With TLS and channel binding does succeed:

        $ gsasl --x509-ca-file=$HOME/.config/mox-localserve/localhost.crt -a 
mox@localhost -p moxmoxmox --imap localhost 1143
        Trying ‘localhost’...
        * OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 
AUTH=SCRAM-SHA-1-PLUS AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STATUS=SIZE STARTTLS 
AUTH=PLAIN] mox imap
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1-PLUS 
AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID APPENDLIMIT=9223372036854775807 CONDSTORE 
QRESYNC STATUS=SIZE STARTTLS AUTH=PLAIN
        . OK CAPABILITY done
        . STARTTLS
        . OK STARTTLS (SREGtbGQrW9XGJovxRtKNw) done
        TLS X.509 Verification: The certificate is trusted. 
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1-PLUS 
AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID APPENDLIMIT=9223372036854775807 CONDSTORE 
QRESYNC STATUS=SIZE AUTH=PLAIN
        . OK CAPABILITY done
        . AUTHENTICATE SCRAM-SHA-256-PLUS
        + 
        
cD10bHMtZXhwb3J0ZXIsLG49bW94QGxvY2FsaG9zdCxyPVRVcGJkRTc5RzB1alhhbHlSckw5SDVrMw==
        + 
cj1UVXBiZEU3OUcwdWpYYWx5UnJMOUg1azNwSHE3NTlhc1M1ZmlnVlROLHM9ZkJBRko2cGdTVXlwOTZudyxpPTQwOTY=
        
Yz1jRDEwYkhNdFpYaHdiM0owWlhJc0xDaEh4dk96amZTVXQwZHNGeTFiNXlKMnRwU2pTc0hRVDBTczl4TS9iUjJGLHI9VFVwYmRFNzlHMHVqWGFseVJyTDlINWszcEhxNzU5YXNTNWZpZ1ZUTixwPXdxaWxOU2paYzRPdE00TFdKSEJOYkxiM1BXRmIyazJmWWRzVU1DNmRRcVU9
        + dj02cHlUTnJjbGJyYnZVcEVNTWIxejExQ1ZvNS9DYVpZRWRoYjVjMnNVS2QwPQ==

        . OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ACCEPT LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256-PLUS AUTH=SCRAM-SHA-256 
AUTH=SCRAM-SHA-1-PLUS AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STATUS=SIZE AUTH=PLAIN] 
authenticate done
        Client authentication finished (server trusted)...


I can think of a few reasons gsasl would pick PLUS when it isn't going to work:

1. The current API doesn't allow checking channel binding data when the auth 
mechanism decision is made.
2. To cause pushback to applications that use gsasl as sasl client, making them 
provide TLS channel binding data.


While doing some more tests with the gsasl cli tool against mox v0.0.8 (that 
only supports bare non-PLUS SCRAM, the following caught my eye, it seems 
SCRAM-SHA-256 fails for a TLS connection when the PLUS variant isn't announced 
(though with mutt using libgsasl, authentication succeeeds and it uses 
SCRAM-SHA-256, so it may be a gsasl-cli-only issue):

        $ gsasl --x509-ca-file=$HOME/.config/mox-localserve/localhost.crt -a 
mox@localhost -p moxmoxmox --imap localhost 1143
        Trying ‘localhost’...
        * OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STARTTLS AUTH=PLAIN] mox imap
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STARTTLS AUTH=PLAIN
        . OK CAPABILITY done
        . STARTTLS
        . OK STARTTLS (k_Emy4FRgGJsG46QFQa3UQ) done
        TLS X.509 Verification: The certificate is trusted. 
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC AUTH=PLAIN
        . OK CAPABILITY done
        . AUTHENTICATE SCRAM-SHA-256
        + 
        gsasl: mechanism error: Error authenticating user

Interestingly, adding --no-cb causes the bare SCRAM to succeed:

        $ gsasl --no-cb 
--x509-ca-file=$HOME/.config/mox-localserve/localhost.crt -a mox@localhost -p 
moxmoxmox --imap localhost 1143
        Trying ‘localhost’...
        * OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STARTTLS AUTH=PLAIN] mox imap
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC STARTTLS AUTH=PLAIN
        . OK CAPABILITY done
        . STARTTLS
        . OK STARTTLS (NPHxlyvIo2D4cIcuLup2NQ) done
        TLS X.509 Verification: The certificate is trusted. 
        . CAPABILITY
        * CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR BINARY 
UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED SPECIAL-USE 
LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC AUTH=PLAIN
        . OK CAPABILITY done
        . AUTHENTICATE SCRAM-SHA-256
        + 
        biwsbj1tb3hAbG9jYWxob3N0LHI9YUV2UWJmaWNTZ0p5ZG9pYXo1RDVYNHhh
        + 
cj1hRXZRYmZpY1NnSnlkb2lhejVENVg0eGF6cENtbVYyNlpoMk0rM2d3LHM9ZkJBRko2cGdTVXlwOTZudyxpPTQwOTY=
        
Yz1iaXdzLHI9YUV2UWJmaWNTZ0p5ZG9pYXo1RDVYNHhhenBDbW1WMjZaaDJNKzNndyxwPXQwLzl1Y2VMN3FhTWFzUFM4MHR5ODEyQXdDTmIzOTVIRGFOazBvdXErZVk9
        + dj1EU1VaWkJ2U1cvVUEwTFhUTFlQMHVlZXBoSDZmVW1aaVhMenlRclFBOUZvPQ==

        . OK [CAPABILITY IMAP4rev2 IMAP4rev1 ENABLE LITERAL+ IDLE SASL-IR 
BINARY UNSELECT UIDPLUS ESEARCH SEARCHRES MOVE UTF8=ONLY LIST-EXTENDED 
SPECIAL-USE LIST-STATUS AUTH=SCRAM-SHA-256 AUTH=SCRAM-SHA-1 AUTH=CRAM-MD5 ID 
APPENDLIMIT=9223372036854775807 CONDSTORE QRESYNC AUTH=PLAIN] authenticate done
        Client authentication finished (server trusted)...
        Enter application data (EOF to finish):


There is a good chance I made some mistakes/wrong assumptions in my analysis, 
rendering followup thoughts wrong. I hope this report is useful in some way.

By the way, in general, I think users/clients should explicitly configure the 
strongest authentication mechanism supported by the server, and not rely on 
automatic mechanism selection: With a MitM, the authentication mechanisms can 
be downgraded, up to choosing "plain login", causing the client to send a plain 
password to the server.

Cheers,
Mechiel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]