help-gsasl
[Top][All Lists]
Advanced

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

Re: Channel binding being attempted even when SCRAM PLUS not advertized


From: Simon Josefsson
Subject: Re: Channel binding being attempted even when SCRAM PLUS not advertized
Date: Mon, 15 Aug 2022 20:06:36 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)

Manvendra Bhangui <mbhangui@gmail.com> writes:

> I have recently added SCRAM-SHA-1, SCRAM-SHA-1-PLUS, SCRAM-SHA-256 and
> SCRAM-SHA-256-PLUS, to my smtp daemon, using gsasl.

Thank you!  Is indimail packaged for some distribution?

> Everything works fine except for one issue. I'm using the gsasl
> utility to test all SCRAM authentication mechanisms. I have the
> ability to turn off SCRAM-SHA-1-PLUS and SCRAM-SHA-256-PLUS in my smtp
> daemon. When I turn off the PLUS variants, gsasl still attempts
> channel binding (tls-exporter) and fails with the following error.
>
> gsasl: mechanism error: Error authenticating user
>
> Debugging I have found the following
>
> 1. the function _gsasl_scram_client_step in lib/scram/client.c gets called
>    it fetches b64 encoded tls-exporter value using gsasl_property_get
>    (sctx, GSASL_CB_TLS_EXPORTER);
>    Since PLUS wasn't advertised, the value of state->plus is NULL and
>    because of this it sets state->cf.cbflag = 'y'. It should have been
>    'n'

It should only ever become 'y' if the callback returned non-NULL channel
binding data, which it should not do when non-PLUS is used.

Try the --no-cb argument to 'gsasl', does it help?

> 2. the function scram_print_client_first() in lib/scram/printer.c gets
>    called which calls the function scram_valid_client_first() in
>    lib/scram/validate.c
>    scram_valid_client_first() returns -1 because of the following line
>
>    else if (cf->cbflag != 'p' && cf->cbname != NULL)
>      return false;
>
> I haven't understood the RFC 5802 but I think the client shouldn't try CB
> when the server has not advertised it at all.

Maybe this paragraph helps:

      *  If the flag is set to "y" and the server supports channel
         binding, the server MUST fail authentication.  This is because
         if the client sets the channel binding flag to "y", then the
         client must have believed that the server did not support
         channel binding -- if the server did in fact support channel
         binding, then this is an indication that there has been a
         downgrade attack (e.g., an attacker changed the server's
         mechanism list to exclude the -PLUS suffixed SCRAM mechanism
         name(s)).

I think that is what is happening here.  See the manual:

https://www.gnu.org/software/gsasl/manual/html_node/SCRAM.html#SCRAM

Note this part:

  The GSASL_CB_TLS_UNIQUE property signal that this side of the
  authentication supports channel bindings. Setting the property will
  enable the SCRAM-SHA-1-PLUS and SCRAM-SHA-256-PLUS mechanisms. For
  clients, this also instructs the SCRAM-SHA-1 and SCRAM-SHA-256
  mechanism to tell servers that the client believes the server does not
  support channel bindings if it is used (remember that clients should
  otherwise have chosen the SCRAM-SHA-1-PLUS mechanism instead of the
  SCRAM-SHA-1 mechanism). For servers, it means the
  SCRAM-SHA-1/SCRAM-SHA-256 mechanism will refuse to authenticate
  against a client that signals that it believes the server does not
  support channel bindings.

> "Clients that do not support mechanism negotiation never use a "y"
> gs2-cbind-flag, they use either "p" or "n" according to whether they
> require and support the use of channel binding or whether they do not,
> respectively."

Libgsasl doesn't know if the client supports mechanism negotiation or
not, so it allows for this situation.

The situation isn't ideal: maybe libgsasl should be informed of the list
of mechanisms offered by the server, to allow it to do the right thing
internally depending on if both PLUS and non-PLUS was announced, or
merely one of them.

Maybe what you found is an unexpected behaviour in the 'gsasl' tool --
the callback shouldn't set CB's when non-PLUS is selected.  It doesn't
have the logic to do that, but you should be able to fake it with
--no-cb.  The idea was that the tool should be as dumb as possible, to
allow you to use --no-cb to manually chose here.  But perhaps the
default for non-PLUS

/Simon

Attachment: signature.asc
Description: PGP signature


reply via email to

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